Android组件化方案
组件化
随着项目功能的增多,单一工程项目下的代码越来越多,编译速度越来越慢。无论采用最初的MVC,还是改进化的MVP和MVVM,都不能很好的的这个问题。从SDK演化而来的组件化,在解决这个问题的时候取得了良好的效果。先看一下组件化模式的结构图如下,分为组件化模式和集成模式
组件化结构图.png
image.png
1、app壳工程
此工程项目下基本没有任何代码,需要在build.gradle配置一些签名信息及依赖相关模块的判断,在AndroidManifest.xml下配置集成模式下项目的一些信息例如主题,名称,图标以及自定义application的引用等。
// 一个字段控制所有模块,打开是集成模式,关闭时组件化模式
implementation project(':common_module')
if (!isModule.toBoolean()) {
implementation project(':main_module')
implementation project(':module_user')
implementation project(':ui_module')
}
// 每个字段控制每个模块 通过字段来决定是否集成到集成模式
if (!isMain.toBoolean()) {
implementation project(':main_module')
}
if (!isUser.toBoolean())
{
implementation project(':module_user')
}
if (!isUi.toBoolean())
{
implementation project(':ui_module')
}
2、第三方库
此目录下放一些第三方功能库、通用组件库和自己封装的库,例如网络库。
引用的第三方库,尽量使用源码,以方便和项目不同的功能或者bug进行修改
3、公共组件
CommonModule公共组件,主要放一些基类,工具类,通用widget和一些通用的库的封住,在values目录下可以放一些常见的颜色和常见的间距字体大小以方便引用,也可以放一些通用的主题。此组件最好放所有项目都能使用的,就是通用的。在不同的项目需要改变的放在CommonData目录下,因为不同的项目中数据时不一致的。将变化和稳定的分开来。build.gradle 文件引用上面的第三方库
dependencies {
api fileTree(dir: 'libs', include: ['*.jar'])
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
api rootProject.ext.dependencies.appcompat_v7
api rootProject.ext.dependencies.support_v4
api rootProject.ext.dependencies.constraint_layout
api rootProject.ext.dependencies.design
api rootProject.ext.dependencies.multidex
api rootProject.ext.dependencies.retrofit
api rootProject.ext.dependencies.retrofit_converter_gson
api rootProject.ext.dependencies.retrofit_adapter_rxjava2
api rootProject.ext.dependencies.urlconnection
api rootProject.ext.dependencies.okhttp_apache
api rootProject.ext.dependencies.okhttp
api rootProject.ext.dependencies.logging_interceptor
api rootProject.ext.dependencies.rxandroid
api rootProject.ext.dependencies.rxjava
api rootProject.ext.dependencies.gson
api rootProject.ext.dependencies.glide
api rootProject.ext.dependencies.fresco
api rootProject.ext.dependencies.eventbus
api rootProject.ext.dependencies.rxbus
api rootProject.ext.dependencies.circleimage
api rootProject.ext.dependencies.cardview
api rootProject.ext.dependencies["tencent-bugly"]
api rootProject.ext.dependencies["stetho"]
api rootProject.ext.dependencies["stetho-okhttp3"]
api rootProject.ext.dependencies["logger"]
implementation project(':baseLib:banner')
implementation project(':baseLib:magicindicator')
implementation project(':baseLib:photoview')
implementation project(':baseLib:pickerview')
implementation project(':baseLib:retrofitrxc')
implementation project(':baseLib:alertview')
implementation project(':baseLib:kprogresshud')
implementation project(':baseLib:viewanimations')
//公共库导入
implementation project(':common_data')
}
为了方便项目管理,我们习惯性的喜欢新建一个config.gradle文件并将这些依赖配置到此文件中,便于管理。这里需要注意的是采用的时api的方式,因为implementation指令是不对外公开的,也就是说其他业务组件依赖common_module后仍然无法引用到retrofit、gson等。
另外此组件中一个比较重要的BaseApplication类,所有的业务组件都需要实现自己的Application,并继承此类。此类内容如下
public class BaseApplication extends Application {
private static final String TAG=BaseApplication.class.getSimpleName();
private static BaseApplication app;
public static BaseApplication getApp() {
return app;
}
@Override
public void onCreate() {
super.onCreate();
app = this;
init();
}
private void init()
{
new Thread()
{
@Override
public void run() {
super.run();
DbHelper.getInstance().init(app.getApplicationContext());
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
CommonApplication.initQDApp(app);
LoaderFactory.getLoader().init(app);
//路由初始化
RouterConfig.init(app, true);
//Stetho调试工具初始化
Stetho.initializeWithDefaults(app);
LogUtils.setShowLog(true);
}
}.start();
}
}
4、ConmonData
此模块主要存放app中的相关数据和针对项目中特定的通用数据,例如数据库,Aroute数据等
5、安全模块
此模块可根据需求不同,可合并到CommonModule模块,或者独立出来。
主要放一些加解密,安全环境检测,签名校验等内容。有些项目对安全性要求比较高,相关代码可以移出来。
image.png
6、业务相关模块
业务模块可根据需要采用不同的适配模式,MVC,MVP,MVVM,根据项目需要采用不同的组织结构
image.png
集成模式下是库,组件化模式下是应用,需要在build.gradle 通过判断来切换。在总的工程根目录的gradle.properties中设置开关,可以每个业务模块设置一个参数,也可以统一设置一个参数。
# Project-wide Gradle settings.
# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
org.gradle.jvmargs=-Xmx1536m
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
# false集成模式true组件化模式
isModule = false
image.png
在每个业务模块下配置build.gradle
if (isModule.toBoolean()) {
apply plugin: 'com.android.application'
} else {
apply plugin: 'com.android.library'
}
在每个业务模块新建debug,存放自定义application(需要集成BaseApplication)和入口Activity,在合并打包时需要删除,在build.gradle中配置如下
image.png
在main包下建个module文件,里面存放AndroidMainfest.xml文件,因为在组件化模式下,项目组件也是可以运行的,所有需要有正常的清单文件。
总结
组件化中Activity之间的跳转和传值主要使用阿里的路由组件,不同组件之间使用主线通信。另外在组件化的时候,由于组件时库,不允许使用switch,资源命名冲突问题都需要注意(资源命名参考编程规范)。另外小项目可以采用组件化思想,以方便集成到其他应用中。,业务组件分的要合适,太大背离组件化的初衷,太小碎片化太严重。最好某一个系统模块放到一起,例如用户系统,主页系统,订单系统。组件化模式下混淆方案可以在各个模块,也可以集中在app壳工程中,但要区别这两种混淆的不同。