美团猫眼android模块化实战-可能是最详细的模块化实战

转载请注明出处:
美团猫眼电影android模块化实战–可能是最详细的模块化实战
地址:http://blog.csdn.net/qq_22744433/article/details/77948442

目录

1 写这篇博客的初衷

首先一句话概括:我想把这几个月做的事情记录下来,并且希望尽量详细,希望读者读了这篇文章能够知道项目进行模块化,项目改业务框架可能会遇到哪些问题,具体每个步骤都做什么,而不是大致的了解。

现在很多人都在谈模块化,网上有一大堆的博客实践都在讲这个。很多谈的只是模块与模块之间的解耦,并且大部分讲的是通过router路由进行解耦,其他谈的不多,而且不乏泛泛而谈。但将一个app真正做到解耦,运行。需要解决的事情远远不止解耦。业务架构、进程间通信、资源等处理、解耦方式等都需要解决。恰好对于猫眼模块化整个过程的实施,从头到尾,分析解决各种问题,我陆陆续续的做了几个月。猫眼app的历史版本是一个耦合度很高的一个工程。从这样的一个历史版本到最终的各个业务模块能够独立运行并且能够做进程间通信,会涉及到各个方面的解耦和一些其他东西。我今天我就以该app为例(其他的app进行解耦可能会遇到不同的问题,这点注意一下),完整的讲下猫眼模块化的整个过程。每一个方面没有照搬网络的一些做法,而是分析对比,采用更好的设计方式。比如解耦使用serviceloader,而不是路由进行;比如架构使用更适合我们业务的一种带生命周期的mvp变种。我还会说下具体的花费时间和一些经验,这样大家以后做模块时也心中有数。(提示一下,其实模块化过程所涉及的东西除了文章提及的还有很多。有些未提及,是因为之前已经完成,比如网络库的缓存由数据库->文本,这点读者注意一下。如果还有遗漏的地方,可以交流~)。

主要内容:serviceloader解耦,mvp变种框架,模块通信,lib独立运行,多端复用。

2 为什么做模块化

首先要说一点:做模块化不是为了炫技。如果没有业务场景需求,不建议做。
为什么要做模块化,网上已经阐述了很多原因了。这里我简单说下猫眼为什么要做:

  • 猫眼需要快速移植到其他app(美团,点评..)。
  • 解耦首页,减少冷启动时间。
  • 开发时减少build时间,代码责任制。
  • 服务快捷替换

3 解耦到什么程度?

首先说下,模块化究竟是什么呢?这个大家肯定都耳熟能详了:能够将不同的业务分离成不同的lib module。那么做完模块化,我们的某个业务lib 具有哪些功能呢?我认为是:

总结一句话:无沟通成本,快速,傻瓜式的在任何app上运行。具体就是:这个lib不耦合具体app的服务,不耦合具体app的activity。只要给我一个app(或假的app壳子),通过它的baseActivity,和他们的服务,我就可以非常快速的将这个lib在那个app上运行。停!你可能会说这个服务是什么东西,让我详细的说下吧~

3.1 可以无侵入式的配置各种服务

我们知道每个app都会提供账户信息,设备信息,网络服务,图片加载服务,打点服务,下拉刷新样式,错误状态等。每一个app的这些服务可能都不一样,比如美团使用的网络服务是okhttp,而点评使用的是长连接。所以我们的业务逻辑lib不能耦合这些具体的服务。只能耦合服务抽象而来的接口。在具体app使用的时候,我们再把app的服务提供给这个lib。那么这些服务怎么给呢?如果当需要服务时,我都留了一个传参的口子,这样我就需要把app的服务一个个塞到lib中需要的地方。这样成本太大了。我不希望这么麻烦,我希望的方式是直接把服务实现作为txt文本放在app的某个文件夹,你这个lib就能给我运行。这样我几乎不用管lib里面是什么东西。你只要给我一个业务lib,我添加一个txt文本,就能运行了。

3.2 lib快速便捷多端使用

说下不耦合activity。我们知道每个app有自己的baseAtivity,在里面做统计,处理异常、某些库的初始化等功能。除此之外,每个app的actionBar也不一样,每个页面在不用的app中manifest的schema也不一样。所以在lib中的业务,如果是一个业务,我们不能直接写成Activity,而应该是一个view/fragment,这样对于任何一个app,我们直接新建一个activty,然后把lib中的页面放到那个activity中即可。同样,考虑的是协同合作的成本问题,我不希望在放这个页面的时候,我需要处理很多其他的东西,比如数据加载。我希望你给我这个业务页面pager(其实是一个view),我放到activity onCreate()的setContentView()中即可,它就能运行。别让我做其他处理生命周期,数据绑定,销毁等的事,那都是你pager内部需要做的。

3.3 demo示例

前面这两点说的可能云里雾里的。最近我写一个猫眼问答需求,涉及5个页面,所以做成了一个lib。那么就结合我最近写的lib来图文阐述一下。

这个lib就是问答的业务lib。这不耦合具体的服务,只耦合服务接口。里面的页面(page包下)不是activity,而是view。
那么,这时候另外一个同事想把这个lib用到猫眼app上。怎么做呢?

  • 在猫眼app的build.gradle下添加这个lib的依赖:

      compile 'com.maoyan.android.business:movie:1.0.2.3'
    
  • 在猫眼宿主app中添加一个lib需要的服务配置:服务实现txt文本(因为是宿主app,之前其实已经存在)。

    txt里面是:

  • 在宿主app中创建activity,并放置lib中的页面,填写manifest,比如(可能有时候需要在里面写入actionBar的交互逻辑)

这就完成了,就运行了。所使用的各种服务,下拉刷新等都是这个app提供的。是不是快速、无需沟通写作、傻瓜。
如果我们想测试这个app,那么也很简单。随便建一个app壳子,新建activity,把lib中的页面page放进去。然后添加所需要的服务实现txt文本(因为是测试,所以服务实现可以自由一些,可随意配置),
就大功告成了。这种方式来修bug调ui,比启动宿主app修改代码节省很多时间。
我们看下我随意写了一个app来测试lib:

我们可以看到下拉刷新,状态服务等和猫眼app中的都不一样,都可以定制。如果都这么写,其实所有的模块我们都可以快速,傻瓜,可定制的做成app~这种解耦程度是不是更好呢~

如果感觉还不错的话,那么我们开始工作吧~


4 开始模块化之旅

4.1 原项目耦合结构

开始模块化工作,我首先得给大家呈现下之前未模块时高度耦合的猫眼app。我们这里以电影详情页为例,看看他的耦合情况:

电影详情页是建立在一层层的基类之上,这些基类耦合了具体的网络加载等各种服务。因为详情页有想看、评分、点赞等可编辑状态,所以还耦合了greendao数据库(以前网络加载也耦合了这个数据库,后来换成了retrofit+rxjava,所以替换到了这层耦合,谢天谢地)。该页面因为需要和其他页面互动(比如跳转、评分同步等),所以也同时耦合了其他页面的类。除此之外,还有utils,view,model等。如果想把电影详情页抽离出来,这些所有的耦合都要剥离。具体需要解决的问题,如下:

4.2 准备工作

4.2.1 工作量评估

首先我们说下解耦时需要做的准备工作。因为这些工作是解耦拆分的基础。有两点需要做,如下所示:

首先说明一下,并不是我喜欢打五颗星。确实是这部分工作量比较大~~~

4.2.2 公共资源,model&
  • 10
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 12
    评论
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值