高h喷水荡肉自慰爽文np你的位置:18禁止观看强奷免费国产大片 > 高h喷水荡肉自慰爽文np > Android模块化架构下,子模块自加载决议!
Android模块化架构下,子模块自加载决议!

发布日期:2022-06-18 16:56    点击次数:167

  

Android模块化架构下,子模块自加载决议!

配景在 Android 模块化架构中后,子Module 间互相解耦,行为孤立的模块运行。要是 子Module 也需要进运行化的操作,那么该奈何做呢?可能你会说,径直在 壳App Application的onCreate函数进走运行化就不错了,但这么会带来一些新的问题:

咱们并不需要 壳App 去关注模块里面的业务,是以每个模块的运行化应该由自身顾问; 并不是通盘子模块的运行化,都需要在 Application onCreate() 时去进行加载,这么会极大影反馈用的启动速率。是以每个模块的运行化应该按需加载;

常见决议及优毛病 1、ContentProvider

杀青旨趣:每个 子Module 里面自界说 ContentProvider ,在应用 Application 的 onCreate 函数实行前,系统就会自动的王法调用 子Module 的 ContentProvider 的 onCreate 函数,也就杀青了 子Module 的自加载功能。举例 WorkManager 亦然阐述这个旨趣,其里面声明了 ContentProvider 来杀青这种自加载决议。

优点:

模块间充领悟耦,代码界限孤立

毛病:

ContentProvider 的启动是有性能损耗的,在子模块较多(业务逻辑较多的 App,可能会有几十个 子Module )的情况下,有一定的性能损耗; 需要袭取 ContentProvider 类并在 AndroidManifes 中声明,代码不够神圣和优雅; 无法截至运行化的时机,在应用启动时就会运行化通盘的子模块,而运行化本人可能即是一件比拟重的业务逻辑; 2、ARouter

杀青旨趣:通过路由的样式,杀青子Module的运行化。

 

界说通用IPreloadProvider接口

interface IPreloadProvider: IProvider {     fun preload() } 

在主module中进走运行化调用

fun ARouter.preload(context: Context, path: String) {     val preloadProvider = this.build(path).navigation(context.applicationContext) as IPreloadProvider     preloadProvider.preload() } 

优点:

在巨额场景下,咱们都会使用 ARouter 来进行模块化联想,而ARouter自然扶持这种路由调用的设施,约略好用; 代码界限孤立,壳App 与 子Modoule 间不需要代码上的径直依赖;

毛病:

壳App需要原谅 子Module 的业务,联想上有一定的耦合; 运行化的代码块容易彭胀,且各个 子Module 的运行化代码均在全部,后续难以阅读和爱护; 3、App Startup

优点:

App Startup 是 为了处分因 App 启动时运行多个 ContentProvider 会增多 App 的启动时辰的问题, 久久被窝亚洲精品爽爽爽使用了一个 InitializationProvider 顾问多个依赖项,根除了每个库单独使用 ContentProvider 资本,减少运行化时辰; App Startup 不错自动运行化 AndroidManifest.xml 文献中 InitializationProvider 底下的 声明要运行化的模块,并允许自界说模块运行化王法; App Startup 提供了一种延伸运行化模块的设施,减少 App 运行化时辰;

毛病:

使用时需要修改 AndroidManifest 文献,使用不够神圣; 子Module 功能比拟孤立,且很厚情况不需要即时加载(不需要在应用启动就进走运行化的动作),要是使用延伸加载的话,又需要使用代码主动实走运行化操作,那么势就必存在对应的援用。而咱们的 子Module 依赖其实是提议使用 runtimeonly ,减少代码上的径直依赖; 无法处分需要时加载这种需求; 加载时序是在 Application onCreate 之前,依赖的通用库此时可能并未被加载见效; 4、决议回归

是以,咱们需要一个模块自加载决议,大致处分上头的问题,且能舒服各式场景的需求:

代码神圣,高h喷水荡肉自慰爽文np使用浮浅,逻辑显然; 子Module 的预加载或者预启动,由 子Module 自身来顾问,幸免与其他模块的逻辑耦合; 加载时机不错截至,能做到即时加载或者懒加载,幸免产素性能损耗; 不产生绝顶的性能损耗(可领受规模内); 模块化自加载决议(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 生成的映射关系。

1、奈何提高ALoader的运行化速率

应用缓存和 Gradle 插件,来莳植映射类的查找速率,杀青高性能的运行化。

 

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      }  } 
决议不及之处和优化点

该决议的最终目标是:通过最约略的样式,杀青模块的按需自加载决议。

然而依然还有不错优化的场所:

App Startup 不错自界说模块运行化王法,在ALoader决议中,是否也需要集成? 通过 Hook 时代来判断子模块的启动,可能存在兼容性问题,是否还有更优雅的样式? 是否有其他更复杂的业务场景,还没筹商到呢?

虽然,关于一般的业务场景,ALoader的杀青照旧裕如舒服需要。要是有其他更好的决议,咱们也不错全部探讨。



Powered by 18禁止观看强奷免费国产大片 @2013-2022 RSS地图 HTML地图