——》个人平时笔记,看到的同学欢迎指正错误,文中多处摘录于各大博主精华、书籍
1、首先组件和模块都不是官方规定的,都是这些技术发展下来大家约定俗成的概念,他们都是一个个Module,只是概念内容不一样而已。
Module包含两种格式: application, library。一个Module就是一个小的项目,Module通过依赖来注入到主app工程中,也是AS概念中的模块。
>1.模块化开发:按照项目业务模块来划分,将一个app按业务拆分为登录模块、聊天模块等等,模块化其中一个核心的目的就是代码的高可复用、高可维护和高可扩展性能。
模块化的概念可以说贯穿整个组件化、插件化。
>2.组件化开发:对应用功能的封装,一个功能一个组件。比如网络连接交互组件、即时通讯IM组件、数据库组件等。是对模块化更小的细分。
正常一个app中可以有多个module,但是一般只会有一个module是设置为application的,其他均设置为library。将一个工程分成各个模块,各个模块之间相互解耦,可以将module均设置为application独立开发并编译成一个独立的 app进行调试,然后又可以将各个模块module均设置为library组合起来整体构成一个完整的 app,这个概念和模块化没有本质的界限。
组件可以分为两大类,一类是application组件,一类是libs组件,application组件是一个可运行的app。library组件可以作为application的依赖,但是自身不可作为程序运行的存在。只有Module类型为application的组件才能单独提出来做为程序运行存在。
组件化是建立在模块化思想上的一次演进,一个变种。组件化本来就是模块化的概念,但是组件具有可以在模块和单独运行的apk之间自由设置切换的特性。即组件化的核心是模块角色的可转换性, 在打包时是library,在调试时是application。
组件只是我们在代码开发阶段中为了方便叫的一个术语,在组件被打包进APP的时候是没有这个概念的,这些组件最后都会被打包成arr包,然后被app壳工程所依赖,在构建APP的过程中Gradle会自动将重复的arr包排除,APP中也就不会存在相同的代码了。
解决以下项目中的问题:
1.稍微改动一个模块的一点代码都要编译整个工程,耗时耗力
2.公共资源、业务、模块混在一起耦合度太高
3.不方便测试
2.插件化开发
宿主是指普通的apk,插件一般是指经过处理的dex或者apk,在主流的插件化框架中多采用经过特殊处理的apk来作为插件,处理方式往往和编译以及打包环节有关。Android应用程序的.java文件在编译期会通过javac命令编译成.class文件,最后再把所有的.class文件编译成.dex文件放在.apk包里面。那么动态加载(插件化)就是在运行时把插件apk直接加载到classloader里面的技术。
目的:插件化就是要减小宿主程序apk包的大小,同时降低宿主程序的更新频率并做到自由装载模块、在线更新模块。
好处:
1.宿主和插件分开编译
2.并发开发
3.动态更新插件
4.按需下载模块
5.方法数或变量数爆棚
总结:
插件化和组件化没有可比拟性,组件化通俗点讲就是一个项目结构设计、架构思路,而插件化是一个新兴技术的应用。组件化在打包编译前按需加入功能模块,插件化在打包完成主apk后将新需要的功能模块单独打包成apk文件插入主apk中。即组件化的单位是组件(module)。插件化的单位是apk(一个完整的应用)。
①组件化:
1. 用于项目过大,每次编译时间长
2. 用于团队多个人分工开发不同的模块
3. 更好的解耦
4.组件化的灵活性在于按加载时机切换,分离出独立的业务功能组件,比如微信的朋友圈
②插件化:
1. 用于版本新添加功能,更多的是启动另一个apk中的activity,或使用另一个apk的资源
2. 解决方法数超过65536问题
3. 按照需要下载模块,减小项目apk的大小
4.本质上它使用的技术还是热修复技术
5.插件化的灵活性在于是加载apk, 完全可以动态下载,动态更新,比组件化更灵活
③热更新(热修复):可以使用第三方的框架,现在都已经很成熟了如:腾讯提供的Bugly
1. 用于修复已经上线的bug等问题
2. 一般不用于新功能的版本上线
3.强调的是修改线上版本的bug,用技术去实现不更新整个apk的条件下,修改掉bug
热更新两种方式:
>>1.阿里系:DeXposed、andfix:从底层二进制入手(c语言)。
>>2.腾讯系:tinker:从java加载机制入手。通过类加载器加载这些修复好的class,覆盖对应有问题的class,理论上就能修复bug了。
Android平台出现了一些优秀的热更新方案,主要可以分为两类:一类是基于multidex的热更新框架,包括Nuwa、Tinker等;另一类就是native hook方案,如阿里开源的Andfix和Dexposed。这样客户端也有了实时修复线上问题的可能。但经过调研之后,我们发现上述方案或多或少都有一些问题,基于native hook的方案:需要针对dalvik虚拟机和art虚拟机做适配,需要考虑指令集的兼容问题,需要native代码支持,兼容性上会有一定的影响;基于Multidex的方案,需要反射更改DexElements,改变Dex的加载顺序,这使得patch需要在下次启动时才能生效,实时性就受到了影响,同时这种方案在android N [speed-profile]编译模式下可能会有问题。
3、组件化的混淆规则:
各个业务组件的混淆配置规则都应该在app壳工程中的混淆配置文件中添加和修改。之所以不采用在每个业务组件中开启混淆的方案,是因为 组件在集成模式下都被 Gradle 构建成了 release 类型的arr包,一旦业务组件的代码被混淆,而这时候代码中又出现了bug,将很难根据日志找出导致bug的原因;另外每个业务组件中都保留一份混淆配置文件非常不便于修改和管理,这也是不推荐在业务组件的 build.gradle 文件中配置 buildTypes (构建类型)的原因。