ITPub博客

首页 > 应用开发 > IT综合 > 一个直播系统源代码的模块自加载方案

一个直播系统源代码的模块自加载方案

IT综合 作者:云豹科技晓彤 时间:2021-10-10 16:58:51 0 删除 编辑

 模块化自加载方案(ALoader)

方案: 每个直播系统源代码子Module 都有自己的 ModuleApplication(虚拟Applicaiton),并定义 启动模式,在应用 Application 启动时,会根据每个 ModuleApplication 的 启动模式来择机调用其 onCreate() 函数,达到直播系统源代码模块自加载的目的。

使用非常方便,仅需要在每个直播系统源代码 子Module 内创建 ModuleApplicaiton 类,继承自 IModuleApplication,使用注解: ModuleApplication 定义 initMode 即可。

@ModuleApplication(initMode = InitMode.MAIN)
class LoginModuleApplication : IModuleApplication() {
    override fun onCreate(context: Context) {
        Log.v("ALoader", "Login Module onCreate")
    }
}

InitMode:

HUNGRY: 饿汉式加载

主要用于加载时机较为严格的场景,即应用启动后,需要立刻加载该 子Module 的相关配置。

IDLE: 空闲时加载

主要用于加载时机不那么严格的场景。即应用启动后,使用 idleHandler 进行初始化,达到空闲时加载的目的。

LAZY: 懒汉式加载

主要用于按需加载的场景。即应用启动后,不进行该 子Module 的初始化操作,待该 子Module 的 Activity 、 Service 或者相关逻辑执行时,才进行 该子Module 的初始化工作,保证功能的正常运行。

自加载方案设计思路

借鉴了ARouter的实现原理,模块自加载方案的核心思想是:通过Apt技术,生成 InitMode(初始化时机) 和 被注解(@ModuleApplication)的组件类 的映射关系的类( ALoaderCore),利用这个保存了映射关系的类,ALoader根据 InitMode 寻找到目标类,执行其onCreate() 函数。该框架的核心是利用 apt 生成的映射关系。

ALoader.png

1、如何提高ALoader的初始化速度

利用缓存和 Gradle 插件,来提升映射类的查找速度,实现直播系统源代码高性能的初始化。

classloader.png

2、如何实现ALoader懒加载的效果

对于 子Module 懒加载的实现,最重要的是直播系统源代码如何识别到该 子Module 开始启动,并在此之前进行初始化的操作。针对于多数的业务场景来讲,子Module 的启动通常是伴随着 四大组件(Activity、Service、ContentProvider、BroadcastReceiver)的启动,而我们可以通过 Hook 技术来实现对四大组件启动的感知,通过包名的匹配来识别到是哪个 子Module 开始启动。以 Activity 和 Service 为例:

    fun hookActivityThreadHHandler() {
        val aClass = Class.forName("android.app.ActivityThread")
        val sCurrentActivityThread: Field = aClass.getDeclaredField("sCurrentActivityThread")
        sCurrentActivityThread.isAccessible = true
        val activityThread = sCurrentActivityThread.get(aClass)
        val mHField: Field = aClass.getDeclaredField("mH")
        mHField.isAccessible = true
        val mh = mHField.get(activityThread) as Handler
        val handlerClass = Class.forName("android.os.Handler")
        val mCallbackField = handlerClass.getDeclaredField("mCallback")
        mCallbackField.isAccessible = true
        mCallbackField.set(mh, ProxyHandlerCallback())
    }
    class ProxyHandlerCallback : Handler.Callback {
        override fun handleMessage(msg: Message): Boolean {
            when (msg.what) {
                LAUNCH_ACTIVITY -> {
                    // TODO: 
                }
                EXECUTE_TRANSACTION -> {
                    // TODO: 
                }
                CREATE_SERVICE -> {
                    // TODO: 
                }
            }
            return false
        }
    }

方案不足之处和优化点

该方案的最终目的是: 通过最简单的方式,实现模块的按需自加载方案。但是依然还有可以优化的地方:

  1. App Startup 可以自定义模块初始化顺序,在ALoader方案中,是否也需要集成?
  2. 通过 Hook 技术来判断子模块的启动,可能存在兼容性问题,是否还有更优雅的方式?
  3. 是否有其他更复杂的业务场景,还没考虑到呢?

当然,对于一般的业务场景,ALoader的实现已经足够满足直播系统源代码需要。如果有其他更好的方案,我们也可以一起探讨。

声明:本文由云豹科技转发自少冰半糖柠檬茶博客,如有侵权请联系作者删除

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70002045/viewspace-2795236/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
音视频软件开发相关知识科普账号

注册时间:2021-06-11

  • 博文量
    163
  • 访问量
    60337