人人都能组件化

作者: 为梦拼命的攻城狮 | 来源:发表于2018-05-26 17:14 被阅读1437次

撸字不易,转载请注明:转自https://www.jianshu.com/p/81d2e0132a10

首先说明,以上不是标题党,而是最近的一些感想,或许我觉得看完这篇文章,只要肯花时间,去进一步消化,组件化方案不难,难的就是拆分的过程,容我一一道来!!

继上家公司把组件化做完之后,经历了线上考验,依然坚挺着。由于个人原因(发展+穷......),四月份辞职了,前往现在的新公司,最近被安排的任务,依然是组件化搭建设计,顺便也做了一次OJT的内部分享,把上家公司组件化的一些感想经验做下分享,以下纯属个人观点,如果有些不对,望各位大佬指出。另外也是对之前写的一篇文章的完善和修改。

首先先把效果图呈上。

一、概念

谈起组件化,会不由的联想到模块化,插件化的概念,他们三者究竟区别在哪?模块化其实是一个很通用的,对于与整个技术领域,当代码冗余到一定程度,将其进行分层解耦,当某个功能,某个控件很多地方会使用,我们把它抽出来,其实都叫模块化。对应于Android领域,就是组件化和插件化。组件化最终打包生产的Apk只有一个,你可以在编译期间把单个组件编译成apk来调试运行。而插件化可以最终打包成多个apk,每个插件可以在apk运行时进行加载。

二、实战

为什么进行组件化,我就简单的说下。因为网上最近关于组件化的文章也很多。自己总结了四个。如上图。图里很详细,其实主要就是把项目解耦,提高构建,开发的效率,另外为之后进行插件化铺路,不过目前如果做插件化对其兼容性考验很大,但是组件化没有这个问题。

做组件化之前首先就是设计方案,因为公司和项目不是你一个人的,你需要设计可行性的方案,让团队信服。因为之前阿里Andfix刚出来的时候,就做过源码分享,到后面的开源的插件化框架Small。本来计划用第三方的,省时省力,但是不省心,因为强扭的瓜不甜,不能硬上,要温柔....万一出问题了不好改,而且不适合现在的项目。那么只能硬着头皮,埋头干!

先给大家看看效果图,后面再慢慢解释。

如果不进行组件化,相信基本每个公司每个项目发展到一定程度都会变成上图的情况,改进之后如下图。为什么两种最后的结构图不同呢?因为他们应用的组件跳转和通信不同,前者是最开始使用的,后者是改进之后的,后面详细说。

这里必须提一下,做组件化,必须对gradle有一定了解和熟悉,不了解的可以把这个视频学完,《新一代构建工具gradle》受益颇多。这个也是做组件化的前提!!

在方案和设计图画好后,进行组件化的第一步就是打造底层Common库。

Common库,一般包含一些基础的公共模块,公共类库,通用控件,基础的BaseActivity,BaseApplication等。再进行拆分时,可以先新建一个module,然后把这些文件通过移动的形式放过去,不要复制,因为这样上层的引用也会自动的改变,不然你得手动一个个去更改。在组件化拆分过程中,不要太心急,可以先把之前的项目作为一个main_module,然后从里面把一个拆的差不多了,再拆另外一个,个人不建议前期并行。并行会导致混乱。

三、方法

总结了一下,组件化方案,基本都必须解决如下几个问题。

1.所谓组件化,就是要做到,打包发布是一个apk,开发阶段,每个组件可以单独调试运行。那么如何自由的在module和library间切换。如何处理好AndroidManifest,gradle.build究竟是application还是library?

2.如果我们在library时添加application,那么整体打包就会报错,但是library切换到module必须要application,怎么解决呢?

3.很多真实业务场景,我们需要A组件跳转到B组件的某个界面,或者给它传递参数。另外,如果A组件化执行完某个任务,需要通知B组件更新,怎么处理?

4.A组件依赖你引入的一个库B,库B里面又依赖库C,但是D组件直接依赖库C,这个时候编译就会报错。

5.真正组件化开发的时候,基本每个组件完全隔离,A组件开发人员对组件A的资源的命名可能会和其他组件冲突。

好了,来一一说明怎么解决,但是解决的前提,还是特别推荐,没有gradle基础的,可以把上面关于gradle的视频看完。

第一个问题:

在项目的gradle.properties里面配置一个全局的常量isModule,通过更改它的值来控制module和library的切换。

在组件各自的buid.gradle里面配置如下,

大概的意思就是,根据isModule的值来判断是用什么地方的文件,还有plugin用什么。这里不做过多解释,demo很详细。

第二个问题:

从前面的配置可以看出,exclude,"debug/**如果是library状态,就不使用debug下面的文件。

可以在debug里面定义所需的moduleApplication,继承放到底层common库的BaseApplication。组件里面的application只需要实现简单的逻辑就行。

第三个问题:

上面最终的架构效果图不一样,主要是引用的第三方库不同,多进程通信方案,学习成本有点高,配置有点麻烦(不是说该方案不好,只是不太适用当前项目),后面改成阿里开源的ARouter。

感兴趣的可以详细的看下,这里不做扩展。简单的介绍一下ARouter和EventBus.

如上图,在B组件某个界面添加@Route注解,然后A组件如果想跳转到B的某个界面,就可以如上代码设置。

EventBus是用来解决,A组件执行完某个任务,需要B组件刷新,本来也可以用广播解决,但是广播不方便管理。但是EventBus使用和广播差不多,都需要注册,发送,处理事件。

第四个问题:

可以使用gradle脚本,exclude 把重复依赖的包去掉,还有种做法,是把依赖文件统一放在一起,gradle会自动使用最新版本替换老版本。我是使用后者。

第五个问题:

可以在组件buid.gradle,添加 resourcePrefix project.name + '_'的配置。不过该配置只针对xml文件,图片资源需要在团队统一命令规范,一般推荐使用组件名加图片名。

四、风险与反思

我一直坚信凡事都会有好坏,就看自己如何抉择。组件化是一项大工程,对项目整个架构更改,基本需要测试把大部分功能都测一遍。(保险起见),其次就是编译时间加长,为什么会这么说?网上很多资料明明说了会加快编译时间。编译时间变长,是真心体会。因为组件化你前期没有办法一步到位,大神除外。前期组件会以library形式存在,而不是aar,就会导致编译时间加长。但是后期稳定成熟,打包成aar了,就会快很多。其次组员需要一定学习成本,这个就是为什么把多进程换成ARouter,ARouter学习成本会小很多。

另外就是对产品的要求,产品在设计的时候也需要遵循组件化。在前期时,我们的底层Common会拆分很多公共模块,这些模块能不动尽量不动,因为你的改动,可能导致其他的依赖有问题。最后就是发版的检查,发版前,需要确保混淆,组件版本是最新版本。

五、Tips

1.因为很多组件都需要buid.gradle,里面基本很多东西都是一样的,可以在主工程新建一个文件夹,然后统一用一个配置,这样方便管理,如图。

2.单独组件开发时,如何知道怎么调用别的组件的情况,可以在每个组件定义一个arouter.json文件,统一管理。不过这个也有点麻烦,每次定义的时候,需要手动在项目的arouter.json文件里添加,如果大家有更好的方案麻烦和我说下。

3.A组件想调用B组件的某个方法,注意,不是跳转界面。其实最开始的demo演示也有。本质是使用ARouter。首先在底层的Common库定义一个接口集成IProvider,然后在B组件实现该方法,最后A组件里面,获取接口的实例,然后调用该方法。

4.GIT组件化部署

可以参考Git 工具 - 子模块

5.Demo地址

AndroidModuleDemo

六、最后

以上是我个人的思路,如果有不对的 地方,望指出,万分感谢。

欢迎关注微信公众号,专注于Android深度文章和移动前沿技术分享

参考资料:

1.http://blog.spinytech.com/2017/02/01/ma_get_start_cn/

2.https://github.com/alibaba/ARouter

3.https://www.jianshu.com/p/f9ae5691e1bb

4.https://github.com/guiying712/AndroidModulePattern

相关文章

  • 人人都能组件化

    撸字不易,转载请注明:转自https://www.jianshu.com/p/81d2e0132a10 首先说明,...

  • 封装组件-面向对象

    tab组件化tab组件化代码 图片曝光组件化图片曝光组件化代码 轮播组件化轮播组件化代码

  • Android组件化 - gradle配置(一)

    一、什么是组件化 什么是组件化呢? 组件化、插件化、模块化之间有什么区别呢? 组件化:每个组件都是独立的功能模块,...

  • Android:插件化

    插件化组件化 组件化与插件化的区别 组件化是Android自然提供的,例如分成lib,test组件。插件化是热更新...

  • iOS 组件化实战篇(私有库)

    前沿 本片文章主要讲解我们项目中为什么要组件化 组件化的好处 怎么使用组件化 怎么实现组件化 为什么要组件化 ...

  • iOS组件化

    iOS组件化 iOS组件化

  • vue零基础开发004——todolist组件化

    1.todolist组件化-全局组件 2.todolist组件化-局部组件

  • Android组件化方案思路

    在进行app组件化之前我们要明白什么是组件化?为什么要组件化? 什么是组件化?为什么要组件化? 在项目的体系结构,...

  • 组件化方案

    组件化方案引用 在现有工程中实施基于CTMediator的组件化方案 iOS组件化实践(一):简介 iOS组件化实...

  • iOS组件化(二)----- 组件的更新

    组件化系列传送门 iOS组件化(一)----- 创建私有组件库(在码云上操作)iOS组件化(二)----- 组件...

网友评论

  • 2b1ed5b649ed:PPT不错
  • ada572ea42e9:eventbus 和arouter 一般不会用了 eventbus 代码可读性太差 arouter 相比正常的router框架来说有点重
  • 6995f5f096fa:转载了您这篇文章,写的很不错
    为梦拼命的攻城狮:@程序圈LT 我试下哈。之前没有弄过。
    6995f5f096fa:@为梦拼命的攻城狮 我想在微信号转,但是你标了原创,可以加个白名单么?
    为梦拼命的攻城狮:谢谢,注明转载的出处就行。:smile:
  • 5d537e2ff587:你好,不知道您现在从事什么行业,但是十分欣赏您的技术,我最近有个项目,想寻个合伙技术人员,是做一个类似商城app的,只不过与传统商城app不同,如果可以的话加个微信联系,v:15244422211
  • CokeNello:楼主,看了你的Demo,是不是可以这样理解,只使用ARouter,就可以完全隔离各个组件,ARouter声明每个组件的对外接口,然后统一使用ARouter来获取相应组件的服务。
    为梦拼命的攻城狮:@栗子酱油饼 我之前也考虑过这个问题,前期开发组件化拆分是不可避免的。后期可以考虑把它单独提出来,比如commonservices,其他不变的打成aar包。这样后面会快点。
    CokeNello:@为梦拼命的攻城狮 我想问个问题,使用ARouter作为组件化方案,每个组件暴露的接口都放在了公共的Common模块中,但在开发阶段,这个接口并不是一开始就确定下来,所以变动很频繁,每一次变动,Common就得重新编译,重新发布,有没有更优雅更好的处理方案呢?
    为梦拼命的攻城狮:@栗子酱油饼 可以这么理解。
  • 浩运:我最近也在琢磨组件化,分享两个想法,1.Arouter用来组件化通信的时候,目标组件会被做成类似单例的方式,对于临时通信交互这个开销需要考虑。2组件通信接口下沉方案可以参考微信架构重构的思路,避免手动修改。
  • 莫离境:pdf 做的不错,最近看了很多组件化的文章的demo,现在大家都大同小异了。
    billy05:确实有很多基于路由的组件化方案,原理相同,具体做法大同小异,不过这篇文章算得上是干货满满了。点个赞!
    BTW,有兴趣了解下不同的方案吗?不用路由,并且可以用一次次小手术代替文中“风险与反思”中的大手术。渐进式组件化框架CC了解一下: https://github.com/luckybilly/CC
  • 3ce5f8801584:这可能是我方圆好久看过的最厉害的一篇文章,厉害的地方在于对外行来说,我居然看完了全部,但是我不懂,还有一个字不认识😆😆😆
    为梦拼命的攻城狮:@3ce5f8801584 :joy: 额,,我以为看到的基本都是Android开发者...

本文标题:人人都能组件化

本文链接:https://www.haomeiwen.com/subject/fmwjjftx.html