Android 架构 - 组件化
一、概念
组件化是基于可重用目的,对单个功能进行开发,提升复用性降低耦合度。多个功能组件起来就是一个业务组件,多个业务组件组合起来就是一个应用,因此去除了模块间的耦合,使得按业务划分的模块成了可单独运行的业务组件。(组件化只是一定程度上的独立,还是依附于整个项目中,想完全独立详见插件化)
- 功能复用:每个组件都是一个单独的功能,可被不同的模块甚至不同的应用所使用。
- 提高效率:每个组件都是一个可单独编译运行的APP,由于拆分使得代码量少,调试起来快。
- 协同开发:组件之间相互独立,使得不同的开发人员能专注于各自的功能开发互不影响。
1.1?需要考虑的问题
组件分层、切换模式按需编译、组件通信(路由框架)、组件生命周期(组件在应用中存在的时间,组件是否可以按照需求动态使用,涉及到组件的加载卸载等管理问题。)
1.2?插件模式
在组件的构建脚本 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'
1.3?创建组件
File→New→New Module。业务组件需要调试选择【Phone &?Tablet】,功能组件(最后还是通过业务组件来调试)基础组件只用来集成选【Android?Library】。?
二、结构划分
依赖关系是上层依赖下层,修改频率是上层高于下层。对于业务组件由于存在页面跳转、方法调用、事件通信等问题需要使用路由通信,其它层组件不存在耦合问题封装成?Library 即可。
app壳 | 主工程,应用的入口,将业务组件打包成一个APP(打包环境、签名、混淆、主题等配置工作)。 |
业务组件 | 业务组件之间无直接关系,通过路由进行通信。既可以作为 Application 单独编译运行调试,又可作为 Library 集成到项目中。(主页、消息、商城) |
功能组件 | 功能组件是为了支撑业务组件的某些功能而独立划分出来的组件(对公用的功能进行封装),功能实质上跟项目中引入的第三方库是一样的。(业务组件可以直接依赖基础组件去实现功能) |
基础组件 | 实现路由、一般是第三方框架、第三方SDK,修改频率极低。(Retrofit、Glide) |
三、统一配置
3.1?创建并引入 config.gradle
创建方式是对 Project?的?build.gradle?使用 Ctrl+C?和?Ctrl+V,命名为 “config.gradle” 清空里面的代码并同步一下,然后在?Project?的?build.gradle?中引用刚才创建的文件。
3.2?切换组件模式的全局变量?isDebug
?
四、基础组件
4.1?创建?lib_common
4.2?提供?BaseApplication
提供?BaseApplication?供app壳和其它组件继承。
4.3?统一权限声明?AndroidManifest
声明了项目中用到的所有权限 user-permission 和 uses-feature,这样其它组件就无需在自己的 AndroidManifest.xm 声明自己要用到的权限了。
?
4.4?统一第三方依赖?build.gradle
????????统一所有组件中用到的第三方库和jar包,具体写在?config.gradle?中再引入。使用 imlemntation?添加的依赖只对当前组件有效,使用 api?添加的依赖对其上层组件同样有效,这样依赖于基础组件的组件就不用再添加相同的依赖了。
????????项目中某个组件会被其它组件重复依赖,在集成构建应用时?Gradle 会剔除重复的 arr?包,这样就不会存在好几份重复的代码了。而第三方库和我们的项目可能都依赖了相同的库(例如?Glide?中也依赖了?OkHttp)就会导致重复加载,解决办法是找出相同的库根据组件名或包名排除。
4.5?公共类
封装了项目中的 Base类、Utis工具类等,公用的 Widget控件、业务组件中都用到的数据也应放在这里(例如 SharedPreferences 和 DataBase 中的登录数据)。
4.6?资源文件
将公共的?drawable、shape、layout、strings、colors、dimens、styles、theme 等资源文件放在这里,提升复用性,保证主题统一、避免文件名冲突。必须放在组件中的话,一定要规范命名前缀。
五、核心组件(业务组件同理)
5.1?创建 module_core
5.2?创建 debug?包
在业务组件中创建?debug?包,用于存放只在组件模式下使用的文件(如程序入口?Launcher?Activity、自定义Application),在集成模式下会被剔除不参与打包(见下方build.gradle中配置)。
在业务组件的?src/main/java?目录上右键→New→Package。(不推荐在组件的其它层级上创建目录存放,切换到Android视图不会显示)
5.3 两份 AndroidManifest
????????在组件模式下,也会因为<application>标签配置、自定义Application 、指定启动入口(Launcher?Activity)而在?AndroidManifest?中进行注册,但在集成模式下打包到一起时存在重复和冲突(桌面上好几个启动图标、只能注册一个自定义的Application、同一个权限无须多次申请)。
? ? ? ? 由于可以在?build.gradle?中动态指定组件的模式,因此可以分别为两种模式加载不同的?AndroidManifest。组件模式下的 AndroidManifest?写在?debug?目录中,在集成模式下剔除。
- 将?AndroidStudio?为组件自动创建的?AndroidManifest?复制一份到?debug?目录,对 <manifest>?标签添加?package 属性指定为业务组件的包名。?
- 修改自动创建的?AndroidManifest,将 <application>?的属性(保留了theme是方便组件中用到该主题的Activity不用每个都要单独设置)以及程序入口?Launcher?Activity 删除,只保留四大组件的注册,对 <manifest>?标签添加?package 属性指定为组件的包名。
5.4 修改 build.gradle
- 在组件模式下才是一个应用,因此需要动态配置 applicationId。
- 在 <android> 标签下使用 <sourceSets> 动态指定不同模式下加载的 AndroidManifest?文件,并剔除?debug?包下的文件不参与集成模式下的打包。
- 将版本替换成?config.gradle?中定义的。
- 在 <dependencies>?中引入依赖。
5.5?程序入口?LauncherActivity
用于初始化数据后启动目标?Activity(不需要可以省略),因此写在?debug?目录下,不用?setContentView(),传入目标?Activity?需要的?Intent?参数即可。
六、搬空app壳
6.1?搬运 MainActivity
将 app 中的 MainActivity.class?和?activity_main.xml?剪切至?module_core?中,并将?AndroidManifest?中的?MainActivity?注册(包含程序入口)也剪切至 module_core?中只保留 <application>?标签。
6.2?修改 AndroidManifest
每个组件都会有自己的清单,最终会打包合并成一个文件,需要解决属性冲突。分别对?app?的 <manifest>?和 <application>?添加如下代码。
manifest?标签 | xmlns:tools="http://schemas.android.com/tools" |
application?标签 | tools:replace="android:label,android:icon,android:theme,android:allowBackup" |
6.3?修改 build.gradle
将 <defaultConfig>?和 <dependencies>?下的配置统一定义到?config.gradle?中并引入,并根据组件模式动态的引入组件。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!