[Android组件化]组件化与插件化优化

以下是我这个系列的相关文章,有兴趣可以参考一下,可以给个喜欢或者关注我的文章。

[Android]如何做一个崩溃率少于千分之三噶应用app--章节列表


记得我之前有介绍了一种非常适合于组件化后做插件化的框架,就是Small。

我在第九章节的时候就有介绍了Small的使用,还有深入分析Small的运行原理

近来使用Small研发插件中,遇到一些问题,就在这里和大家讨论一下。

这里说一下Small的的一些缺陷,

(1)其不支持动态Service,Service都只能放在宿主里面了。

(2)Small暂时是只能通过冷更新(就是完全重启App时才能加载,如果有更新,当你按home键或者返回键退出,其会将整个Process杀死重启),源码中木有在运行途中增


这一篇的简书,理解难度将会加大,因为公司代码就不宜张贴啦,如果同学没有项目木有实现过插件化的,理解起来会有一定的瓶颈。

1.关于插件化选型

可以参考以下文章

基础看

Android客户端插件化热修复各种方案对比和最全总结

深入看这个

Android插件化从入门到放弃-最强合集

估计看完这些你就快可以疯掉了。^_^

选型基本需要考虑的问题

1.对四大组件的支持(hook点支持)

2.so库支持

3.打包时资源冲突

4.更新方式和时机


2.插件间通信

每个插件都是基于base的module去开发,那么通过这个base module那么我们就可以通过ModuleBus或者路由的机制完成传输了。

Small本身定义的OpenUri来启动对应的模块,并未有提供可以传递各种参数的方法。

而我们是通过自定义一个PluginManager封装,类似之前介绍的分发机制去封装一个方法标志字符串标志,然后传输intent,context,viewgroup等对象,通过PluginManager遍历过滤再传输到对应的插件模块,其他需要传输的信息都可以封装到intent里面。


3.资源冗余问题

你想像一下,如果你每个工程会依赖baseApi,那么编译生成的base 的module,当生成xxx.so文件的时候,不就会出现一份冗余的base module代码和资源吗?

这个问题其实Small有自定义的编译代码,其自己写了一套编译的groovy代码,所以在编译的时候重复依赖的module移除了。

Small的编译代码,如果没点gradle构建工程基础和groovy编译想法的确不容易找到

我这里简单指明一下吧

之前说了使用DevSample查看Small的源码,这里编译的最终配使用的是AppPlugin


然后可以看到解决依赖的方法通过,过滤掉D.txt里面的所要依赖的


通过app-D.txt compile.exclude掉这些依赖的库


通过afterEvaluate最终加载这个过滤方法。


AppPlugin这里也会有将每个module里面生成的R.txt重复的资源id过滤掉,还有保留public.txt的id

这里publicEntries是保存的public.txt里面的内容,而bundle.Entries保存的是R.txt的内容的


bundleEntries是过滤掉重复的R id的算法。


如果不熟悉Gradle构建流程,也不打算深入了解的,就不需要深究了。

这里只要知道,每个module都编译的时候都共有一份D.txt R.txt和public.txt,然后small的构建会过滤掉相同的资源。然后编译出来的so文件插件运行的时候,还是通过一样的资源id来索引到公用的base module的内容。

那么为了增强每个功能模块的独立性,每个功能module都独立成为一个工程(Small的这个工程模块只是独立成一个module),那么要怎么处理才能使工程都去除资源重复呢?

这里其实也很简单,我们保证我们都依赖的自定义扩展的Small库,base的module是被宿主module引用的,那么需要保证其生产的D.txt和R.txt和public.txt,其他的module都需要持有(手动或者配置下载到其他的module里面),然后编译的时候修改加入遍历这些txt的资源文件。

4.重复触发

我在一个插件module里面发送一个信号,然后多个module都需要接受这些信号,那么如何控制其它module接收顺序,或者触发顺序调节呢?给个选择题吧

(1)插件提供判断参数给触发插件,将触发顺序的逻辑都写在触发插件里面。(这里还需要考虑如果插件不存在的判空问题)

(2)将触发的逻辑分发到其他插件,然后通过插件获取其他插件的状态(没启动或者不需要处理)而去判断是否做相应的操作

这里需要考虑到充分解耦的问题,因为代码调整的触发逻辑,控制不好我们很可能需要更替一个或者多个module,就因为一个修改就更替module,这样的设计是非常不好的。估计有人肯定觉得这些方案都不适合吧。

那么我就提供第三种方案吧。

(3)PluginManager在发送信号到其他插件时候,在发送前做过滤操作,需要过滤什么信号,就需要读取一个列表过滤列表(通过包名过滤或者信号名过滤),做成服务器可配置,那么随时都可以转换顺序触发逻辑了。

如果你看到这里有更好的解耦方案,也可以提出来,让我们继续学习。

5.全局弹框

有人是否有想过Android的弹框(自定义Dialog)是怎么弹出来的?

你想要在任意页面里面可以弹出提示的弹框需要如何做?

我们弹出弹框需要依赖于window,并且我们创建dialog的时候需要顶层Activity的Content对象

那么我们需要如何可以获取到顶层的Activity的Content对象呢?

这里面Application可以提供该顶层Activity时候的声明周期,作出回调,然后我们可以通过做成base

Module保存,其他插件获取context实现或者直接获取弹框对象。(这里面需要api level 14)



6.最重要的提醒

我们最希望的是不能让插件的任何调用会嵌入到宿主module或者其他插件的module,任何通信最好还是通过底层base module做的通信来协议来做,因为一旦木有判空,插件移除将会影响到宿主或者其他插件崩溃。



这节就到这里,希望对大家有一定的帮助。

如果你有更好的建议,请在评论中留言,我会和各位继续相互讨论,谢谢!

下一节将会更精彩!!!



我建立了一个关于Android架构学习的群,里面可以进一步进行组件化学习和架构思想的的交流。

群号是316556016,也可以扫码进群。我在这里期待你们的加入!!!


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值