一种在 Library 模块中调用 Application 模块功能的方法

上一篇分享中,我介绍的主题是如何在一个 Android 项目中使用 AppJoint 进行组件化。有读者找到我说:我知道组件化很美好,可是项目改造老是须要成本的,并且这个成本是咱们目前承受不了的,咱们目前能作的最多的只能是 模块化,即把主 app 模块的功能拆出来,放到新的 library 模块里,但目前面临的最直接的问题就是,拆出来的新模块如何调用主 app 模块里的方法。可否不用组件化那一整套工具,先用 最轻量级的方法 解决这个跨模块方法调用的问题?java

答案固然是确定的,AppJoint 就是这样一个轻量级的工具,若是你不想组件化,那么你彻底能够把它当成一个只是用来解决跨模块方法调用的问题的小工具。git

问题背景

假设目前已经从 app 模块拆出了一个 module1 模块,app 模块是主 app 模块, 而 module1 模块是 library 模块。若是 module1 模块想要调用 app 模块的功能,那么确定须要存在一个接口,这个接口两个模块要都能访问到。因此这个接口存在的位置就只能是 app 模块和 module1 模块都依赖的公共模块。这里的这个公共模块,它能够是已有的公共模块,也能够是新建立的公共模块。咱们在这个公共模块里声明这个接口,即 app 模块但愿被 module1 模块调用的方法的接口:github

interface AppService {

  // start Activity from app module
  fun startActivityOfApp(context: Context)

  // get Fragment from app module
  fun obtainFragmentOfApp(): Fragment

  // call synchronous method from app module
  fun callMethodSyncOfApp(): String

  // call asynchronous method from app module
  fun callMethodAsyncOfApp(callback: AppCallback<AppEntity>)

  // get RxJava Observable from app module
  fun observableOfApp(): Observable<AppEntity>
}
复制代码

这个接口因为处于公共模块,因此两个模块都能访问到这个接口。接下来咱们就来解决这个问题,即在 module1 模块里调用 app 模块的方法。app

问题解决

在声明上面这个接口之后,咱们在 app 模块里实现这个接口:async

@ServiceProvider
class AppServiceImpl : AppService {
  override fun startActivityOfApp(context: Context) {
    AppActivity.start(context)
  }

  override fun obtainFragmentOfApp(): Fragment {
    return AppFragment.newInstance()
  }

  override fun callMethodSyncOfApp(): String {
    return "syncMethodResultApp"
  }

  override fun callMethodAsyncOfApp(callback: AppCallback<AppEntity>) {
    Thread { callback.onResult(AppEntity("asyncMethodResultApp")) }.start()
  }

  override fun observableOfApp(): Observable<AppEntity> {
    return Observable.just(AppEntity("rxJavaResultApp"))
  }
}
复制代码

须要注意一点,咱们在实现类上标记了 @ServiceProvider 注解。而后咱们就能够像下面这样,从 module1 模块里调用 app 模块里的方法了:ide

val appService = AppJoint.service(AppService::class.java)

// call methods inside AppService
appService.callMethodSyncOfApp()
appService.observableOfApp().subscribe()
appService.startActivityOfApp(context)
...
复制代码

即便咱们没有引入组件化的任何概念,咱们也能轻松解决模块化中最常碰见的跨模块方法调用的这一类问题。模块化

关于如何在项目中引入 AppJoint,能够前往 AppJoint 的 Github 主页:github.com/PrototypeZ/…, 核心代码不超过 500 行,您能够使用开箱即用的版本,也能够自行在项目中引入。工具

参考资料

在模块化以后,您可能会对项目的组件化产生兴趣,欢迎继续阅读个人组件化经验分享 『回归初心:极简 Android 组件化方案 — AppJoint』,但愿能够给您的项目组件化带去一点点帮助,谢谢! : )组件化


若是您对个人技术分享感兴趣,欢迎关注个人我的公众号:麻瓜日记,不按期更新原创技术分享,谢谢!:)post

相关文章
相关标签/搜索