组件化是基于可重用目的,对单个功能进行开发,提升复用性降低耦合度。多个功能组件起来就是一个业务组件,多个业务组件组合起来就是一个应用,因此去除了模块间的耦合,使得按业务划分的模块成了可单独运行的业务组件。(组件化只是一定程度上的独立,还是依附于整个项目中,想完全独立详见插件化)
组件分层、切换模式按需编译、组件通信(路由框架)、组件生命周期(组件在应用中存在的时间,组件是否可以按照需求动态使用,涉及到组件的加载卸载等管理问题。)
在组件的构建脚本 build.gradle?中指定,指定为集成模式(Library)可以被其它组件调用,指定为组件模式(Application)可以独立运行调试。
com.android.application | 项目构建后输出?apk 包,在调试时是一个应用能单独编译运行。 |
com.android.library | 项目构建后输出 aar 包,在打包时是一个库文件集成到项目中。 |
//写法一(和别的一起写)
plugins {
id 'com.android.library'
id 'org.jetbrains.kotlin.android'
}
//写法二(分开写)
apply plugin: 'com.android.library'
File→New→New Module。业务组件需要调试选择【Phone &?Tablet】,功能组件(最后还是通过业务组件来调试)基础组件只用来集成选【Android?Library】。?
依赖关系是上层依赖下层,修改频率是上层高于下层。对于业务组件由于存在页面跳转、方法调用、事件通信等问题需要使用路由通信,其它层组件不存在耦合问题封装成?Library 即可。
app壳 | 主工程,应用的入口,将业务组件打包成一个APP(打包环境、签名、混淆、主题等配置工作)。 |
业务组件 | 业务组件之间无直接关系,通过路由进行通信。既可以作为 Application 单独编译运行调试,又可作为 Library 集成到项目中。(主页、消息、商城) |
功能组件 | 功能组件是为了支撑业务组件的某些功能而独立划分出来的组件(对公用的功能进行封装),功能实质上跟项目中引入的第三方库是一样的。(业务组件可以直接依赖基础组件去实现功能) |
基础组件 | 实现路由、一般是第三方框架、第三方SDK,修改频率极低。(Retrofit、Glide) |
创建方式是对 Project?的?build.gradle?使用 Ctrl+C?和?Ctrl+V,命名为 “config.gradle” 清空里面的代码并同步一下,然后在?Project?的?build.gradle?中引用刚才创建的文件。
?
提供?BaseApplication?供app壳和其它组件继承。
声明了项目中用到的所有权限 user-permission 和 uses-feature,这样其它组件就无需在自己的 AndroidManifest.xm 声明自己要用到的权限了。
?
????????统一所有组件中用到的第三方库和jar包,具体写在?config.gradle?中再引入。使用 imlemntation?添加的依赖只对当前组件有效,使用 api?添加的依赖对其上层组件同样有效,这样依赖于基础组件的组件就不用再添加相同的依赖了。
????????项目中某个组件会被其它组件重复依赖,在集成构建应用时?Gradle 会剔除重复的 arr?包,这样就不会存在好几份重复的代码了。而第三方库和我们的项目可能都依赖了相同的库(例如?Glide?中也依赖了?OkHttp)就会导致重复加载,解决办法是找出相同的库根据组件名或包名排除。
封装了项目中的 Base类、Utis工具类等,公用的 Widget控件、业务组件中都用到的数据也应放在这里(例如 SharedPreferences 和 DataBase 中的登录数据)。
将公共的?drawable、shape、layout、strings、colors、dimens、styles、theme 等资源文件放在这里,提升复用性,保证主题统一、避免文件名冲突。必须放在组件中的话,一定要规范命名前缀。
在业务组件中创建?debug?包,用于存放只在组件模式下使用的文件(如程序入口?Launcher?Activity、自定义Application),在集成模式下会被剔除不参与打包(见下方build.gradle中配置)。
在业务组件的?src/main/java?目录上右键→New→Package。(不推荐在组件的其它层级上创建目录存放,切换到Android视图不会显示)
????????在组件模式下,也会因为<application>标签配置、自定义Application 、指定启动入口(Launcher?Activity)而在?AndroidManifest?中进行注册,但在集成模式下打包到一起时存在重复和冲突(桌面上好几个启动图标、只能注册一个自定义的Application、同一个权限无须多次申请)。
? ? ? ? 由于可以在?build.gradle?中动态指定组件的模式,因此可以分别为两种模式加载不同的?AndroidManifest。组件模式下的 AndroidManifest?写在?debug?目录中,在集成模式下剔除。
用于初始化数据后启动目标?Activity(不需要可以省略),因此写在?debug?目录下,不用?setContentView(),传入目标?Activity?需要的?Intent?参数即可。
将 app 中的 MainActivity.class?和?activity_main.xml?剪切至?module_core?中,并将?AndroidManifest?中的?MainActivity?注册(包含程序入口)也剪切至 module_core?中只保留 <application>?标签。
每个组件都会有自己的清单,最终会打包合并成一个文件,需要解决属性冲突。分别对?app?的 <manifest>?和 <application>?添加如下代码。
manifest?标签 | xmlns:tools="http://schemas.android.com/tools" |
application?标签 | tools:replace="android:label,android:icon,android:theme,android:allowBackup" |
将 <defaultConfig>?和 <dependencies>?下的配置统一定义到?config.gradle?中并引入,并根据组件模式动态的引入组件。