是官方Demo中的内容,拷贝出来便于查看
一、AppInit:Android 应用初始化框架
二、AppInit-使用文档
三、AppInit-设计文档
第四部分是个人使用记录
四、个人框架使用和理解
[Download ][(https://api.bintray.com/packages/bingoogolapple/maven/bga-appinit-plugin/images/download.svg)]
:https://bintray.com/bingoogolapple/maven/bga-appinit-plugin/_latestVersion
[PRs Welcome][(https://img.shields.io/badge/PRs-welcome-brightgreen.svg)]
https://github.com/bingoogolapple/AppInit/pulls
AppInit 是一款 Android 应用初始化框架,基于组件化的设计思路,功能灵活,使用简单。
AppInit 用于解决美团收银 B 端 App 在业务演进过程中的实际问题,取得了不错的效果,因此我们决定将其开源,希望更多技术同行一起开发,应用到更广泛的场景里去。
随着业务的快速发展,新项目新业务不断出现,以及项目组件化的实施,项目里需要初始化的业务模块和 SDK 也逐渐增多,而且有些业务模块间可能有着错综复杂的依赖关系,在项目开发和测试人员不足、新加入开发同学不熟悉项目的情况下,难免会出现少测漏测的情况,如何使各模块初始化代码解耦、按正确的顺序初始化是我们需要思考的问题。

使用文档:https://github.com/bingoogolapple/AppInit/blob/master/docs/user-manual.md
设计文档:https://github.com/bingoogolapple/AppInit/blob/master/docs/imgs/comparison.png
使用文档和设计文档也记录到下面了。
# 更新日志
## Version 1.0.8 (2020-04-05)
- 从 JCenter 迁移到 JitPack,Gradle 依赖由「cn.bingoogolapple:bga-appinit-plugin」变为「com.github.bingoogolapple.AppInit:buildSrc」
## Version 1.0.7 (2020-03-26)
- 改由个人账号维护,Gradle 依赖由「com.sankuai.erp.component:appinit-plugin」变为「cn.bingoogolapple:bga-appinit-plugin」
- v1.0.7 扫描 jar 包时捕获一下异常
## Version 1.0.6 (2019-10-29)
- v1.0.6 fix #15 兼容 gradle 4.1
## Version 1.0.5 (2019-04-14)
- v1.0.5 修复 Windows 下 rebuild 时提示无法删除 app\build\intermediates\transforms\xxx\debug\xxx.jar
## Version 1.0.4 (2019-04-13)
- v1.0.4 去掉对 commons-io:2.6 的依赖
## Version 1.0.3 (2019-02-19)
- Fix #10 兼容 rootProject 目录以数字开头
## Version 1.0.2 (2019-01-30)
- Fix #6 minSdkVersion 改为 16
## Version 1.0.1 (2019-01-25)
- Fix #1 不支持增量编译的 Transform 在消费上游文件前需要先清除输出目录的文件
- Fix #3 Transform 里获取 Variant 的方式可以更优雅一些
## Version 1.0.0 (2019-01-23)
- 第一个开源版本
AppInit 于 2019 年 1 月 21 日以公司名义在 Meituan-Dianping 账号下开源 ,并于 2020 年 1 月 13 日停止从 Meituan-Dianping 账号开源。
由于之前开源的 1 年时间内已经有开发者将 AppInit 应用到了实际项目中,后续业务项目升级 Gradle 版本后可能也需要 AppInit 升级进行兼容,且在之前开源的 1 年时间内已经大量 Fork,因此再次 Fork 一份到个人账号下进行维护。代码包名不变,为了便于后续上传 JitPack,Gradle 依赖由「com.sankuai.erp.component:appinit-plugin」变为「com.github.bingoogolapple.AppInit:buildSrc」

classpath "com.github.bingoogolapple.AppInit:buildSrc:最新版本号"
20220908最新版本:1.0.8
apply plugin: 'bga-appinit-plugin'
apply plugin: 'kotlin-kapt'
Kotlin版:
class App : Application() {
override fun onCreate() {
super.onCreate()
Log.d(TAG, "onCreate: ")
AppInitManager.get().init(this, object : SimpleAppInitCallback() {
/**
* 开始初始化
*
* @param isMainProcess 是否为主进程
* @param processName 进程名称
*/
override fun onInitStart(isMainProcess: Boolean, processName: String?) {
// TODO 在所有的初始化类之前初始化
AppInitLogger.d("onInitStart")
}
/*
* 是否为 debug 模式
*/
override fun isDebug(): Boolean {
return true
}
/**
* 通过 coordinate 自定义依赖关系映射,键值都是 coordinate。「仅在需要发热补的情况下才自定义,否则返回 null」
*
* 排序含义: KEY 在 VALUE 前面
*
* @return 如果返回的 map 不为空,则会在启动是检测依赖并重新排序,返回null也行
*/
override fun getCoordinateAheadOfMap(): MutableMap<String, String> {
val coordinateAheadOfMap: MutableMap<String, String> = HashMap()
// coordinateAheadOfMap["Demo_AppInit:module3:Module3ThreeInit"] =
// "Demo_AppInit:lib_behavioural_analysis:Behavioural2Init"
// coordinateAheadOfMap[ "Demo_AppInit:lib_behavioural_analysis:Behavioural2Init"] =
// "Demo_AppInit:module3:Module3ThreeInit"
return coordinateAheadOfMap
}
/**
* 同步初始化完成
*
* @param isMainProcess 是否为主进程
* @param processName 进程名称
* @param childInitTableList 初始化模块列表
* @param appInitItemList 初始化列表
*/
override fun onInitFinished(
isMainProcess: Boolean,
processName: String?,
childInitTableList: MutableList<ChildInitTable>?,
appInitItemList: MutableList<AppInitItem>?
) {
super.onInitFinished(
isMainProcess,
processName,
childInitTableList,
appInitItemList
)
// 获取运行期初始化日志信息
val initLogInfo: String =
AppInitApiUtils.getInitOrderAndTimeLog(childInitTableList, appInitItemList)
AppInitLogger.d("onInitFinished :$initLogInfo")
}
})
}
override fun onTerminate() {
super.onTerminate()
AppInitManager.get().onTerminate()
}
override fun onConfigurationChanged(newConfig: Configuration) {
super.onConfigurationChanged(newConfig)
AppInitManager.get().onConfigurationChanged(newConfig)
}
override fun onLowMemory() {
super.onLowMemory()
AppInitManager.get().onLowMemory()
}
override fun onTrimMemory(level: Int) {
super.onTrimMemory(level)
AppInitManager.get().onTrimMemory(level)
}
companion object {
private const val TAG = "App"
}
}
编写初始化类继承 SimpleAppInit,并添加 AppInit 注解,根据具体初始化场景重写相应方法。这里以初始化 Router 举例
Java :
@AppInit(
priority = 40,//优先级
description = "初始化路由",
onlyForDebug = false,
process = Process.MAIN
)
class RouterInit : SimpleAppInit() {
override fun onCreate() {
Log.d(TAG, "RouterInit onCreate: ")
// SimpleAppInit 中包含了 mApplication 和 mIsDebug 属性,可以直接在子类中使用
// Router.initialize(mIsDebug)
}
}
| 属性 | 描述 | 默认值 |
|---|---|---|
| description | 初始化的描述信息 | “” |
| aheadOf | 在指定初始化项之前初始化,用于整个项目范围内重新排序。生成规则为「模块唯一标识:初始化SimpleName」 | “” |
| onlyForDebug | 初始化是否仅在 debug 时可用 | false |
| process | 在哪个进程初始化。可选值为 Process.MAIN(主进程)、Process.ALL(所有进程)、Process.OTHER(其他进程) | Process.MAIN(主进程) |
| priority | 模块内部范围内初始化类的优先级,值越小越先初始化 |
所有方法都是可选的,都只会运行在你注册的进程
| 方法 | 描述 |
|---|---|
| boolean needAsyncInit() | 是否需要异步初始化,默认为 false |
| void asyncOnCreate() | Application#onCreate() 时异步调用 |
| void onCreate() | Application#onCreate() 时同步调用 |
| void onConfigurationChanged(Configuration newConfig) | Application#onConfigurationChanged(Configuration) 时调用 |
| void onLowMemory() | Application#onLowMemory() 时调用 |
| void onTerminate() | Application#onTerminate() 时调用 |
| void onTrimMemory(int level) | Application#onTrimMemory(int) 时调用 |
「模块父目录名称:模块名称」,如:
「POM_GROUP_ID:POM_ARTIFACT_ID」或「GROUP_ID:ARTIFACT_ID」,如:

「模块唯一标识:初始化类的SimpleName」,如:Maven

本地

APP_INIT_DEPENDENCIES=com.sankuai.erp.component:appinit-test-module1,appinit:module2
这种方式会覆盖通过 APP_INIT_DEPENDENCIES 配置的依赖appInit {
// 自定义模块间初始化的依赖关系,会覆盖通过 APP_INIT_DEPENDENCIES 配置的依赖关系
dependency([
'demo:app' : ['com.sankuai.erp.component:appinit-test-module1', 'appinit:module2'],
'appinit:module2' : 'com.sankuai.erp.component:appinit-test-module3'
])
}
/**
* 通过 coordinate 自定义依赖关系映射,键值都是 coordinate。「仅在需要发热补的情况下才自定义,否则返回 null」
*
* @return 如果返回的 map 不为空,则会在启动时检测依赖并重新排序
*/
@Override
public Map<String, String> getCoordinateAheadOfMap() {
Map<String, String> coordinateAheadOfMap = new HashMap<>();
coordinateAheadOfMap.put("appinit:module2:Module2FiveInit", "cn.bingoogolapple:appinit-test-module1:Module1FiveInit");
return coordinateAheadOfMap;
}
2018-11-20 11:43:53
处理 aheadOf 前的顺序为:
《com.sankuai.erp.component:appinit-test-module1》[priority=1]
* [com.sankuai.erp.component:appinit-test-module1:Module1FiveInit][20][进程=MAIN][description=模块15的描述]
* [com.sankuai.erp.component:appinit-test-module1:Module1TwoInit][90][进程=OTHER][description=模块12的描述]
* [com.sankuai.erp.component:appinit-test-module1:Module1OneInit][100][进程=MAIN][aheadOf=com.sankuai.erp.component:appinit-test-module1:Module1TwoInit][description=模块11的描述]
* [com.sankuai.erp.component:appinit-test-module1:Module1ThreeInit][300][进程=MAIN][description=模块13的描述]
* [com.sankuai.erp.component:appinit-test-module1:Module1FourInit][300][进程=MAIN][description=模块14的描述]
《com.sankuai.erp.component:appinit-test-module3》[priority=2][dependencies=com.sankuai.erp.component:appinit-test-module1]
* [com.sankuai.erp.component:appinit-test-module3:Module3FiveInit][5][进程=MAIN][description=模块35的描述]
* [com.sankuai.erp.component:appinit-test-module3:Module3FourInit][10][进程=MAIN][description=模块34的描述]
* [com.sankuai.erp.component:appinit-test-module3:Module3ThreeInit][50][进程=MAIN][description=模块33的描述]
* [com.sankuai.erp.component:appinit-test-module3:Module3OneInit][60][进程=ALL][description=模块31的描述]
* [com.sankuai.erp.component:appinit-test-module3:Module3TwoInit][60][进程=MAIN][aheadOf=com.sankuai.erp.component:appinit-test-module1:Module1OneInit][description=模块32的描述]
《appinit:module2》[priority=3][dependencies=com.sankuai.erp.component:appinit-test-module3]
* [appinit:module2:Module2FiveInit][10][进程=MAIN][description=模块25的描述]
* [appinit:module2:Module2FourInit][40][进程=MAIN][aheadOf=com.sankuai.erp.component:appinit-test-module3:Module3FourInit][description=模块24的描述]
* [appinit:module2:Module2TwoInit][70][进程=MAIN][description=模块22的描述]
* [appinit:module2:Module2ThreeInit][80][进程=MAIN][description=模块23的描述]
* [appinit:module2:Module2OneInit][80][进程=ALL][description=模块21的描述]
《demo:app》[priority=4][dependencies=appinit:module2, com.sankuai.erp.component:appinit-test-module1]
* [demo:app:RouterInit][40][进程=MAIN][description=初始化路由]
* [demo:app:AppFirst][1000][进程=MAIN][description=壳工程最先初始化服务]
最终的初始化顺序为:
《com.sankuai.erp.component:appinit-test-module1》[priority=1]
* [com.sankuai.erp.component:appinit-test-module1:Module1FiveInit][20][进程=MAIN][description=模块15的描述]
《com.sankuai.erp.component:appinit-test-module3》[priority=2][dependencies=com.sankuai.erp.component:appinit-test-module1]
* [com.sankuai.erp.component:appinit-test-module3:Module3TwoInit][60][进程=MAIN][aheadOf=com.sankuai.erp.component:appinit-test-module1:Module1OneInit][description=模块32的描述]
《com.sankuai.erp.component:appinit-test-module1》[priority=1]
* [com.sankuai.erp.component:appinit-test-module1:Module1OneInit][100][进程=MAIN][aheadOf=com.sankuai.erp.component:appinit-test-module1:Module1TwoInit][description=模块11的描述]
* [com.sankuai.erp.component:appinit-test-module1:Module1TwoInit][90][进程=OTHER][description=模块12的描述]
* [com.sankuai.erp.component:appinit-test-module1:Module1ThreeInit][300][进程=MAIN][description=模块13的描述]
* [com.sankuai.erp.component:appinit-test-module1:Module1FourInit][300][进程=MAIN][description=模块14的描述]
《com.sankuai.erp.component:appinit-test-module3》[priority=2][dependencies=com.sankuai.erp.component:appinit-test-module1]
* [com.sankuai.erp.component:appinit-test-module3:Module3FiveInit][5][进程=MAIN][description=模块35的描述]
《appinit:module2》[priority=3][dependencies=com.sankuai.erp.component:appinit-test-module3]
* [appinit:module2:Module2FourInit][40][进程=MAIN][aheadOf=com.sankuai.erp.component:appinit-test-module3:Module3FourInit][description=模块24的描述]
《com.sankuai.erp.component:appinit-test-module3》[priority=2][dependencies=com.sankuai.erp.component:appinit-test-module1]
* [com.sankuai.erp.component:appinit-test-module3:Module3FourInit][10][进程=MAIN][description=模块34的描述]
* [com.sankuai.erp.component:appinit-test-module3:Module3ThreeInit][50][进程=MAIN][description=模块33的描述]
* [com.sankuai.erp.component:appinit-test-module3:Module3OneInit][60][进程=ALL][description=模块31的描述]
《appinit:module2》[priority=3][dependencies=com.sankuai.erp.component:appinit-test-module3]
* [appinit:module2:Module2FiveInit][10][进程=MAIN][description=模块25的描述]
* [appinit:module2:Module2TwoInit][70][进程=MAIN][description=模块22的描述]
* [appinit:module2:Module2ThreeInit][80][进程=MAIN][description=模块23的描述]
* [appinit:module2:Module2OneInit][80][进程=ALL][description=模块21的描述]
《demo:app》[priority=4][dependencies=appinit:module2, com.sankuai.erp.component:appinit-test-module1]
* [demo:app:RouterInit][40][进程=MAIN][description=初始化路由]
* [demo:app:AppFirst][1000][进程=MAIN][description=壳工程最先初始化服务]
scan 耗时:243ms
handle 耗时:201ms
transform 耗时:487ms

appInit {
abortOnNotExist true
}
appInit {
// AndroidManifest.xml 中配置的 Application 的类全名
applicationCanonicalName 'com.sankuai.erp.component.appinitdemo.App'
}
接入方不用再在 Application 中手动写以下代码
public void onTerminate() {
super.onTerminate();
AppInitManager.get().onTerminate();
}
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
AppInitManager.get().onConfigurationChanged(newConfig);
}
public void onLowMemory() {
super.onLowMemory();
AppInitManager.get().onLowMemory();
}
public void onTrimMemory(int level) {
super.onTrimMemory(level);
AppInitManager.get().onTrimMemory(level);
}
public interface IAppInit {
boolean needAsyncInit();
void onCreate();
void asyncOnCreate();
void onTerminate();
void onConfigurationChanged(Configuration newConfig);
void onLowMemory();
void onTrimMemory(int level);
}
public final class AppInitManager {
private List mAppInitList = new ArrayList<>();
public static AppInitManager get() ...
private AppInitManager() {
mAppInitList.add(new BaseConfigInit()) // 初始化基础配置
mAppInitList.add(new RobustInit()) // 初始化热修复
mAppInitList.add(new PushInit()) // 初始化消息推送服务
...
}
private void onCreate() {
// 遍历 mAppInitList 并同步分发给各个初始化类
}
public void onTerminate() ...
public void onConfigurationChanged(Configuration newConfig) ...
public void onLowMemory() ...
public void onTrimMemory(int level) ...
}
为了解决上面的问题,需要我们的初始化框架具备以下特点:
每个初始化类添加 AppInit 注解,注解中传递 priority 参数(整个项目范围内的初始化顺序优先级),通过 APT 收集所有添加了 AppInit 注解的初始化类和对应的 AppInit 注解参数信息,将这些信息写入到特定位置,运行期反射获取这些信息并排序。这里业界有两种方式:
private void writeModuleCanonicalNameAssetFile(Filer filer, String canonicalName) {
Writer writer = null;
try {
FileObject fileObject = filer.createResource(StandardLocation.CLASS_OUTPUT, "", "assets/AppInit/" + canonicalName);
writer = fileObject.openWriter();
} catch (Exception e) {
// 处理异常
} finally {
// 关闭流
}
}
运行期通过 AssetManager 获取每个模块的初始化类列表,反射加载类,实例化完所有初始化类再进行排序,最后再由 ApplicationDispatcher 分发应用生命周期AssetManager assetManager = mApplication.getResources().getAssets();
String[] childInitTableCanonicalNameArr = assetManager.list('AppInit');
运行期通过反射加载 MasterInitTable,并对所有的初始化类进行排序,最后再由 ApplicationDispatcher 分发应用生命周期这两种方式存在的问题:
相较于前两个版本的改进点如下:
处理 aheadOf 前的顺序为:
《com.sankuai.erp.component:appinit-test-module1》[priority=1]
* [com.sankuai.erp.component:appinit-test-module1:Module1FiveInit][20][进程=MAIN][description=模块15的描述]
* [com.sankuai.erp.component:appinit-test-module1:Module1TwoInit][90][进程=OTHER][description=模块12的描述]
* [com.sankuai.erp.component:appinit-test-module1:Module1OneInit][100][进程=MAIN][aheadOf=com.sankuai.erp.component:appinit-test-module1:Module1TwoInit][description=模块11的描述]
* [com.sankuai.erp.component:appinit-test-module1:Module1ThreeInit][300][进程=MAIN][description=模块13的描述]
* [com.sankuai.erp.component:appinit-test-module1:Module1FourInit][300][进程=MAIN][description=模块14的描述]
《com.sankuai.erp.component:appinit-test-module3》[priority=2][dependencies=com.sankuai.erp.component:appinit-test-module1]
* [com.sankuai.erp.component:appinit-test-module3:Module3FiveInit][5][进程=MAIN][description=模块35的描述]
* [com.sankuai.erp.component:appinit-test-module3:Module3FourInit][10][进程=MAIN][description=模块34的描述]
* [com.sankuai.erp.component:appinit-test-module3:Module3ThreeInit][50][进程=MAIN][description=模块33的描述]
* [com.sankuai.erp.component:appinit-test-module3:Module3OneInit][60][进程=ALL][description=模块31的描述]
* [com.sankuai.erp.component:appinit-test-module3:Module3TwoInit][60][进程=MAIN][aheadOf=com.sankuai.erp.component:appinit-test-module1:Module1OneInit][description=模块32的描述]
《appinit:module2》[priority=3][dependencies=com.sankuai.erp.component:appinit-test-module3]
* [appinit:module2:Module2FiveInit][10][进程=MAIN][description=模块25的描述]
* [appinit:module2:Module2FourInit][40][进程=MAIN][aheadOf=com.sankuai.erp.component:appinit-test-module3:Module3FourInit][description=模块24的描述]
* [appinit:module2:Module2TwoInit][70][进程=MAIN][description=模块22的描述]
* [appinit:module2:Module2ThreeInit][80][进程=MAIN][description=模块23的描述]
* [appinit:module2:Module2OneInit][80][进程=ALL][description=模块21的描述]
《demo:app》[priority=4][dependencies=appinit:module2, com.sankuai.erp.component:appinit-test-module1]
* [demo:app:RouterInit][40][进程=MAIN][description=初始化路由]
* [demo:app:AppFirst][1000][进程=MAIN][description=壳工程最先初始化服务]
最终的初始化顺序为:
《com.sankuai.erp.component:appinit-test-module1》[priority=1]
* [com.sankuai.erp.component:appinit-test-module1:Module1FiveInit][20][进程=MAIN][description=模块15的描述]
《com.sankuai.erp.component:appinit-test-module3》[priority=2][dependencies=com.sankuai.erp.component:appinit-test-module1]
* [com.sankuai.erp.component:appinit-test-module3:Module3TwoInit][60][进程=MAIN][aheadOf=com.sankuai.erp.component:appinit-test-module1:Module1OneInit][description=模块32的描述]
《com.sankuai.erp.component:appinit-test-module1》[priority=1]
* [com.sankuai.erp.component:appinit-test-module1:Module1OneInit][100][进程=MAIN][aheadOf=com.sankuai.erp.component:appinit-test-module1:Module1TwoInit][description=模块11的描述]
* [com.sankuai.erp.component:appinit-test-module1:Module1TwoInit][90][进程=OTHER][description=模块12的描述]
* [com.sankuai.erp.component:appinit-test-module1:Module1ThreeInit][300][进程=MAIN][description=模块13的描述]
* [com.sankuai.erp.component:appinit-test-module1:Module1FourInit][300][进程=MAIN][description=模块14的描述]
《com.sankuai.erp.component:appinit-test-module3》[priority=2][dependencies=com.sankuai.erp.component:appinit-test-module1]
* [com.sankuai.erp.component:appinit-test-module3:Module3FiveInit][5][进程=MAIN][description=模块35的描述]
《appinit:module2》[priority=3][dependencies=com.sankuai.erp.component:appinit-test-module3]
* [appinit:module2:Module2FourInit][40][进程=MAIN][aheadOf=com.sankuai.erp.component:appinit-test-module3:Module3FourInit][description=模块24的描述]
《com.sankuai.erp.component:appinit-test-module3》[priority=2][dependencies=com.sankuai.erp.component:appinit-test-module1]
* [com.sankuai.erp.component:appinit-test-module3:Module3FourInit][10][进程=MAIN][description=模块34的描述]
* [com.sankuai.erp.component:appinit-test-module3:Module3ThreeInit][50][进程=MAIN][description=模块33的描述]
* [com.sankuai.erp.component:appinit-test-module3:Module3OneInit][60][进程=ALL][description=模块31的描述]
《appinit:module2》[priority=3][dependencies=com.sankuai.erp.component:appinit-test-module3]
* [appinit:module2:Module2FiveInit][10][进程=MAIN][description=模块25的描述]
* [appinit:module2:Module2TwoInit][70][进程=MAIN][description=模块22的描述]
* [appinit:module2:Module2ThreeInit][80][进程=MAIN][description=模块23的描述]
* [appinit:module2:Module2OneInit][80][进程=ALL][description=模块21的描述]
《demo:app》[priority=4][dependencies=appinit:module2, com.sankuai.erp.component:appinit-test-module1]
* [demo:app:RouterInit][40][进程=MAIN][description=初始化路由]
* [demo:app:AppFirst][1000][进程=MAIN][description=壳工程最先初始化服务]



根据实际情况重写 Application 对应的生命周期方法


生成的类在 build/generated/source/apt/debug/com/sankuai/erp/component/appinit/generated 目录下,该类中包含模块唯一标识,依赖的其他模块,以及该模块中所有的初始化条目








module 5 依赖 lib_behavioural_analysis,需要在module 5中添加 gradle.properties 文件,内容如下:

APP_INIT_DEPENDENCIES=Demo_AppInit:lib_behavioural_analysis
主工程的设置会优先级高于module设置的
修改build.gradle文件

appInit {
// 自定义模块间初始化的依赖关系,会覆盖通过 APP_INIT_DEPENDENCIES 配置的依赖关系
dependency([
'Demo_AppInit:app' : ['Demo_AppInit:module5', 'Demo_AppInit:lib_behavioural_analysis'],
])
// 依赖的模块或 aheadOf 指定的初始化不存在时是否中断编译,默认为 true
abortOnNotExist true
}
优先级最低,统筹module内部
@AppInit(
priority = 40,//优先级
description = "初始化路由",
onlyForDebug = false,
process = Process.MAIN
)
class RouterInit : SimpleAppInit() {
override fun onCreate() {
AppInitLogger.demo("onCreate $TAG")
}
}
@AppInit(
priority = 20,//优先级
description = "初始化MMKV",
onlyForDebug = false,
process = Process.MAIN
)
class MMKVInit : SimpleAppInit() {
override fun onCreate() {
super.onCreate()
AppInitLogger.demo("onCreate $TAG")
MMKV.initialize(mApplication)
}
}
MMKVInit 会在RouterInit 前面执行
@AppInit(
priority = 2,
description = "模块3的描述"
aheadOf = "Demo_AppInit:lib_behavioural_analysis:Behavioural2Init"
)
class Module3ThreeInit : SimpleAppInit() {
override fun onCreate() {
AppInitLogger.demo("onCreate $TAG")
}
}
aheadOf 可以指定两个module之间的类排序
在谁前面的意思,优先级高于priority
优先级最高
/**
* 通过 coordinate 自定义依赖关系映射,键值都是 coordinate。「仅在需要发热补的情况下才自定义,否则返回 null」
*
* 排序含义: KEY 在 VALUE 前面
*
* @return 如果返回的 map 不为空,则会在启动是检测依赖并重新排序
*/
override fun getCoordinateAheadOfMap(): MutableMap<String, String> {
val coordinateAheadOfMap: MutableMap<String, String> = HashMap()
coordinateAheadOfMap["Demo_AppInit:module3:Module3ThreeInit"] =
"Demo_AppInit:lib_behavioural_analysis:Behavioural2Init"
// coordinateAheadOfMap[ "Demo_AppInit:lib_behavioural_analysis:Behavioural2Init"] =
// "Demo_AppInit:module3:Module3ThreeInit"
return coordinateAheadOfMap
}
dependency([
'Demo_AppInit:app': [ 'Demo_AppInit:lib_behavioural_analysis','Demo_AppInit:module5'],
写错了后面依赖的模块名,clean无法解决编译错误的问题,必须重启AS
99%的内容来自Github的Demo,因为不得劲看,特意记录,地址:
美团的AppInit: https://github.com/bingoogolapple/AppInit
其他启动框架:
阿里的alpha:https://github.com/alibaba/alpha