Android模块化设计方案系列文章:
1、Android模块化设计方案模型图
2、Android模块化设计方案之接口API化
3、Android模块化设计方案之使用代理模式解耦
4、Android模块化设计方案之sourceSets配置
5、Android模块化设计方案之启动器
在文章的开始,我先抛出来两个问题:
问题一 :众所周知,随着我们App的规模越来越膨胀,在Application里面要做的初始化的业务逻辑和三方类库越来越多,直接影响就是App的冷启动速度,同时也让代码的可读性变差,如何合理的管理这些初始化任务?
问题二 :在进行模块化开发的时候,总有一些模块要初始化一些本模块特有业务或类库,如何在修改/新增本模块初始化项的时候,尽可能的不修改其他的模块包括壳工程模块在内?
为了解决这两个困惑本打已久的问题,本打Google了许久也没有找到一个比较合适的方案,既然没有现成的轮子用,也只能花点时间打磨一个轮子出来了,于是基于APT技术,打造了这个轮子,它就是启动器——XStarter
那么什么是启动器?
其实就是一个对项目中一些需要初始化的逻辑进行统一管理调度的工具类库,它可以通过简单的配置就能实现启动项的加载顺序以及是否延迟初始化或者在子线程中进行初始化,而且本身支持模块化的设计,能够最大程度做到项目解耦。那么下面我就简单介绍一下XStarter的使用方式吧。
项目源码地址:https://github.com/wangkunhui/XStarter
第一步,引入项目依赖,starter_version = "1.0.0-rc"。
在Java模块中:
android {
defaultConfig{
javaCompileOptions {
annotationProcessorOptions {
arguments = [STARTER_MODULE_NAME: project.getName()]
}
}
}
}
dependencies {
implementation "com.wangkh.moduler:XStarter:$starter_version"
annotationProcessor "com.wangkh.moduler:XStarter-compiler:$starter_version"
}
在Kotlin模块中:
apply plugin: 'kotlin-kapt'
kapt {
arguments {
arg("STARTER_MODULE_NAME", project.getName())
}
}
dependencies {
implementation "com.wangkh.moduler:XStarter:$starter_version"
kapt "com.wangkh.moduler:XStarter-compiler:$starter_version"
}
第二步,在Application中进行注册。
XStarter.isDebug = true // 是否为测试模式
XStarter.emit(DemoApplication.instance) // 开启启动器
第三部,在需要初始化数据的模块中创建启动器类。
@Starter(mainProcessOnly = false)
class KotlinStarter : IStarter { // 类名可以任意命名
@StarterMethod(priority = 99, isSync = false, isDelay = true)
public fun initTest(application:Application) { //方法名可以任意命名
//TODO 执行模块中需要初始化的逻辑
}
@StarterFinish(listen = "initTest")
public fun listenTest(e:Exception) { // 监听initTest方法是否执行完毕,如果不需要监听,可以不写listenTest方法
Log.e("KotlinStarter", "test初始化完成")
}
@StarterMethod(priority = 60, isSync = true, isDelay = true)
public fun initTest2() { //方法名可以任意命名
//TODO 初始化另外一些东西,由于这个方法下初始化不需要用到Application,所以参数为空就行。
}
}
只需要通过以上代码,项目在启动的时候就会自动的寻找KotlinStarter类并调用生命的初始化方法initTest,如果需要监听initTest是否已经执行完毕,可以定义一个监听方法listenTest(方法名可以任意命名),但是其注解@StarterFinish的参数listen中的字符串一定要与被监听的方法名保持一致即可。
注解及参数说明
@Starter // 标注启动管理类
mainProcessOnly -- 是否只在主进程初始化 true 只在主进程中初始化 false 所有进程都进行初始化
@StarterMethod //标注启动方法,只能用到@Starter修饰的类中,否则无效。
priority -- 该启动方法的优先级,[0-99],数值越大优先级越高,默认50;
isSync -- 是否同步初始化(即在主线程中进行初始化操作),true 是 false 不是,即可以在子线程中进行初始化,默认true;
isDelay -- 是否可以延迟初始化,true 是 false 不是,立即初始化,不延迟,默认false;
@StarterFinish //启动方法的监听方法,只能用到@Starter修饰的类中,否则无效。
listen -- 要监听方法的方法名,必填参数;
混淆配置
-keep public class com.wang.android.starter.executor.**{*;}
-keep public class com.wang.android.starter.manager.**{*;}
最后,我们在梳理一下文章最开始时候留下的两个问题。
问题一:原本那些需要在Application类中进行初始化的类库被解耦到各个业务模块里面,剥离了Application中的业务代码,并且提供了统一的方式进行处理。只需要通过简单的注解配置,就能指定该类库的初始化优先级、初始化线程和是否可以延迟初始化,不需要做额外的改动。
问题二:由于Application中的业务代码被彻底剥离,在我们需要对模块的启动类库进行修改或新增模块的时候,只需要去对应Module的启动器类中修改就可以了,无需更改壳工程中的代码。
实现思路是通过APT技术在编译时生成对启动器类的代理类和管理类,通过管理类对所有启动器中的方法进行统一调度。
好了,关于启动器的部分就介绍完毕了,如果该文章能够帮到你,欢迎点赞评论和关注,一起交流探讨~
网友评论