一種在 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

相關文章
相關標籤/搜索