JDispatcher-高效的 Android 组件生命周期分发框架

JDispatcher

晓理动码_光头哥.png

Android 组件生命周期分发框架,适用于组件化,模块化,启动优化等场景
Github : JDispatcher

功能介绍

  • 实现 Application 各个生命周期方法在所有需要的组件中分发

  • 分发顺序支持多种规则

    • 优先级:优先级值越大越先被调用

    • 依赖项:组件依赖的分发类先初始化

    • 支持自动校正在优先级和依赖项两种规则交叉使用情况下的分发顺序

  • 分发维度支持多种规则

    • 在指定进程(所有进程,主进程,非主进程)中分发

    • 在指定线程(主线程,空闲线程,工作线程)中分发,实现异步加载

    • 支持通过非阻塞式异步通知机制实现异步加载与同步加载交叉使用的情况(todo)

    • 手动延迟调用分发,实现延迟加载

    • 通过 ContentProvider 实现在 Application 之前超前预加载(todo)

    • 只在debug模式下分发,实现 DevTools、DoKit 等开发工具的初始化

  • 维度值采用对整型 or/and 的位操作完成多维度值的收集与识别,灵活且高效

  • 支持初始化时批量传参,可用于多项目多环境的三方 sdk 的初始化,使环境配置更统一

  • 通过注解打点,APT 增量收集分发类,降低耦合,可用于模块化,组件化场景

  • 通过拦截 AGP 构建流程实现在编译期间对分发类的扫描和排序,提高运行时性能

  • AGP Transform 增量支持编译(todo)

  • 通过 ASM 字节码插桩实现分发表和 Application 生命周期回调方法的自动注入,集成更高效

  • 支持统计所有分发类的初始化时间,可用于启动优化的统计与排查

框架结构

  • jdispatcher-annotation

    • 模块类型:apply plugin: 'java'

    • 模块描述:声明编译时所需的注解类以及公共类等

  • jdispatcher-compiler

    • 模块类型:apply plugin: 'java'

    • 模块描述:编译期(.java--.class阶段) 收集和处理整个工程中的Dispatch注解信息并通过 javapoet 生成辅助类文件 JDispatcher$$Group_hash.java

  • jdispatcher-plugin

    • 模块类型:apply plugin: 'groovy'

    • 模块描述:编译期(.class--.dex阶段) 自定义Transform拦截AGP的构建过程,找到所有Dispatch并排序

    • 模块主要工作:

      • 第一个:IDispatch 的分发流程

        • 扫描到所有 APT 生成的 JDispatcher$$Group_hash.java 文件

        • 反射获取收集到的 Map<String, DispatchItem> atlas)

        • 通过 atlas 集合收集到的 DispatchItem 实现对 IDispatch 对象的反射实例化

        • 按照 DispatchItem 的排序规则完成排序操作

        • 将排好序的 IDispatch 集合通过字节码插桩到 JDispatcher 中,运行时执行对所有 IDispatch 的分发操作

      • 第二个:Application 生命周期方法的自动注册流程

        • 通过调用方在gradle中配置的 Application 全类名,在自定义Transform中扫描到该类

        • JDispatcher 调用字节码注入到 onTerminate()

        • JDispatcher 调用字节码注入到 onConfigurationChanged(newConfig: Configuration)

        • JDispatcher 调用字节码注入到 onLowMemory()

        • JDispatcher 调用字节码注入到 onTrimMemory(level: Int)

  • jdispatcher-api

    • 模块类型:apply plugin: 'com.android.library'

    • 模块描述:运行时用于整个框架的初始化,运行时分发等操作

集成说明

//Step 1. Add the JitPack repository to your build file
//buildscript & allprojects
allprojects {
    repositories {
        ...
        maven { url 'https://jitpack.io' }
    }
}
//dependencies
classpath 'com.github.jaydroid1024.JDispatcher:jdispatcher-plugin:$last_version'

//Step 2. Add the dependency
implementation 'com.github.jaydroid1024.JDispatcher:jdispatcher-api:$last_version'
kapt 'com.github.jaydroid1024.JDispatcher:jdispatcher-compiler:$last_version'

//Step 3. apply the plugin and config dispatcher
apply plugin: 'jdispatcher'
dispatcher {
    appCanonicalName = "com.jay.android.App"
    buildIncremental = false
    buildDebug = true
}

使用说明

class App : Application() {
    override fun onCreate() {
        super.onCreate()
        //为分发类指定自定义参数,用于三方key的统一收口配置
        val dispatchExtraParam = HashMap<String, HashMap<String, String>>()
        dispatchExtraParam["com.jay.android.jdispatcher.DispatcherAppDemo"] =
            if (BuildConfig.DEBUG) hashMapOf(
                Pair("key1", "value1_debug"),
                Pair("key2", "value2_debug")
            )
            else hashMapOf(
                Pair("key1", "value1_release"),
                Pair("key2", "value2_release")
            )

        //自动分发
        JDispatcher.instance
            .withDebugAble(true)//调试模式:打印更多日志,实时刷新等
            .withDispatchExtraParam(dispatchExtraParam)//分发参数
            .init(this)
    }
  
  
// region如果在 app build.gradle 中配置了
// dispatcher {appCanonicalName = "com.jay.android.App"}
// 就不需要添加以下代码,dispatcher 插件会自动注入

    override fun onTerminate() {
        super.onTerminate()
        JDispatcher.instance.onTerminate()
    }

    override fun onConfigurationChanged(newConfig: Configuration) {
        super.onConfigurationChanged(newConfig)
        JDispatcher.instance.onConfigurationChanged(newConfig)
    }

    override fun onLowMemory() {
        super.onLowMemory()
        JDispatcher.instance.onLowMemory()
    }

    override fun onTrimMemory(level: Int) {
        super.onTrimMemory(level)
        JDispatcher.instance.onTrimMemory(level)
    }
//endregion
}
//手动调用分发
JDispatcher.instance
    .manualDispatch("com.jay.android.jdispatcher.DispatcherAppDemo")

···
//声明分发类
@Dispatch(priority = Priority.LOW_DEFAULT, description = "DispatcherAppDemo")
public class DispatcherAppDemo extends DispatchTemplate {

@Override
public void onCreate(@NotNull Application app, @NotNull DispatchItem dispatchItem) {
    Log.d("Jay", "DispatcherAppDemo#onCreate" + dispatchItem);
}

@Override
public void onConfigurationChanged(@NotNull Configuration newConfig) {
    Log.d("Jay", "DispatcherAppDemo#onConfigurationChanged" + newConfig);
}

@Override
public void onLowMemory() {
    Log.d("Jay", "DispatcherAppDemo#onLowMemory");

}

@Override
public void onTerminate() {
    Log.d("Jay", "DispatcherAppDemo#onTerminate");

}

@Override
public void onTrimMemory(int level) {
    Log.d("Jay", "DispatcherAppDemo#onTrimMemory" + level);

}

}

#Jdispatcher 混淆配置
-keep public class com.jay.android.dispatcher.**{*;}
-keep class * implements com.jay.android.dispatcher.common.IDispatch{*;}

Todo

  • 支持通过非阻塞式异步通知机制实现异步加载与同步加载交叉使用的情况

  • 通过 ContentProvider 实现在 Application 之前超前预加载

  • AGP Transform 增量支持编译

参考

  • ARouter 是一个用于帮助 Android App 进行组件化改造的框架 —— 支持模块间的路由、通信、解耦

  • AppInit 是一款 Android 应用初始化框架,基于组件化的设计思路,功能灵活,使用简单。

  • WMRouter 是一款Android路由框架,基于组件化的设计思路,有功能灵活、使用简单的特点]

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,242评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,769评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,484评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,133评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,007评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,080评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,496评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,190评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,464评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,549评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,330评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,205评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,567评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,889评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,160评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,475评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,650评论 2 335

推荐阅读更多精彩内容