Android 組件化通訊庫

ServiceAssistant(服務助手)

github 地址

ServiceAssistant

介紹

為組件化而生, 可以輕松靈活實現(xiàn)組件之間的任何通信及交互。

主要功能

  • 支持組件之間通信 (懶加載哦)
  • 支持數據注入(這個功能也必須安排上)(懶加載注入哦)

支持亮點

  • 庫特別 mini, 核心庫就幾個類而已
  • 組件之間的任意通訊
  • 組件之間的回調實現(xiàn)
  • 組件之間的數據共享
  • 上層可以輕松調用下層(A 依賴 B, 可實現(xiàn) B 對 A 的任意訪問)
  • 輕松支持數據注入
  • 更加靈活(你想怎么都行)

依賴

在項目 gradle 中配置

repositories {
    maven {
            url "https://gitee.com/xiaoxigexiaoan/warehouse/raw/master"
        }
    }

    dependencies {
        classpath "cn.xiaoxige.serviceassistant:plugin:xxx"
    }
}

allprojects {
    repositories {
        maven {
            url "https://gitee.com/xiaoxigexiaoan/warehouse/raw/master"
        }
    }
}

在 APP gradle 中配置

# 引入插件
apply plugin: 'service-assistant'
apply plugin: 'kotlin-kapt'

# 加入核心依賴
dependencies {
    implementation 'cn.xiaoxige.serviceassistant:core:xxx'
    kapt 'cn.xiaoxige.serviceassistant:processor:xxx'
}

注:

1. 插件只需也僅僅要在 application 中加入

2. 如果要使用注入功能, 記得要加上 kapt 依賴哈, 尤其在依賴庫使用時不要忘記加入哦

至此配置完成, 開啟組件之旅。

核心思想

A 和 B 兩個互不依賴的庫(也包含 A 依賴 B, B 需要訪問 A 的操作)。比如 B 需要訪問 A, 那么必須知曉 A 提供出來了什么能力。 所以 A 需要拋出一系列接口能力(當然這些拋出的能力肯定是誰拋出誰去實現(xiàn), 這里肯定是 A 實現(xiàn)), B 去依賴 A 的接口, 就可以輕松訪問 A 的能力。 那么 B 依賴 A 的接口, 怎么就調用到 A 的實現(xiàn)了呢? 這就是該庫所要做的事情!

通訊模型

類介紹(一共就 5 個類)

name desc
interface IService<T> 提供服務的服務的接口
annotation class Service 提供服務的注解
object Service 服務獲取
annotation class NeedInjected 提供注入的實現(xiàn)類的注解
annotation class Injected 變量注入注解

提供能力的實現(xiàn)一定要繼承 IService 接口?。?!并加入 @Service 注解?。?!

使用注入, 在實現(xiàn)接口類上加入 @NeedInjected 注解! 在使用的接口變量上加入 @Injected 注解!

簡易使用篇(更多操作, 比如組件回調等,請運行和參考 Demo)

比如賬戶組件需要登錄組件的登錄及用戶信息
登錄組件提供的 Api 接口能力中(詳情可見 Demo 中的 LoginApi):

interface IUserInfoApi {

    /**
     * 是否登錄
     */
    fun isLogin(): Boolean

    /**
     * 獲取用戶 id
     */
    fun getUserId(): String
}

interface ILoginAbilityApi {

    /**
     * 登錄
     */
    fun toLogin(context: Context)

    fun addLoginStateChangedListener(listener: ILoginStateChangedListener)

    fun removeLoginStateChangeListener(listener: ILoginStateChangedListener)

    interface ILoginStateChangedListener {
        fun change(state: Boolean)
    }
}

登錄組件中相關能力實現(xiàn)(詳情可見 LoginComponent)

@Service
class UserInfoApiImpl : IService<IUserInfoApi>, IUserInfoApi {
    /**
     * 使用方提供
     */
    override fun getService(): IUserInfoApi {
        return UserInfoApiImpl()
    }

    /**
     * 是否登錄
     */
    override fun isLogin(): Boolean {
        return UserInfo.isLogin
    }

    /**
     * 獲取用戶 id
     */
    override fun getUserId(): String {
        return UserInfo.userId
    }

}

@Service
class LoginAbilityApiImpl : IService<ILoginAbilityApi>, ILoginAbilityApi {


    /**
     * 使用方提供
     */
    override fun getService(): ILoginAbilityApi {
        return LoginAbilityApiImpl()
    }
    
    override fun toLogin(context: Context) {
        LoginActivity.showActivity(context)
    }

    override fun addLoginStateChangedListener(listener: ILoginAbilityApi.ILoginStateChangedListener) {
        sLoginStateChangedListener.add(listener)
    }

    override fun removeLoginStateChangeListener(listener: ILoginAbilityApi.ILoginStateChangedListener) {
        sLoginStateChangedListener.remove(listener)
    }

    companion object {
        private val sLoginStateChangedListener =
            mutableListOf<ILoginAbilityApi.ILoginStateChangedListener>()

        fun notifyLoginState(state: Boolean) {
            sLoginStateChangedListener.forEach {
                it.change(state)
            }
        }
    }

}

賬戶組件獲取登錄信息 (詳情可見 AccountComponent)

Service.getService(IUserInfoApi::class.java)?.let {
    tvUserInfo.text = if (it.isLogin()) "userId: ${it.getUserId()}" else "未登錄"
}

賬戶組件去跳登錄界面, 相信聰明的你已經不用我再復制了吧。 (詳情可見 App, Demo 中我是在 App 去跳的登錄界面)

注入使用

這個使用過于簡單, 當然也相信使用其他注入框架跟多了, 這里就簡單一個例子。

  1. 定義需要注入的類:
// 定義接口
interface ISettingRepo {

    fun getSettingInfo(): String
}

// 進行實現(xiàn)
@NeedInjected(false)
class SettingRepoImpl : ISettingRepo {

    override fun getSettingInfo(): String {
        return "網絡請求得到的 setting 結果"
    }

}

  1. 進行使用
class MainActivity : AppCompatActivity() {

    @Injected
    private lateinit var mAboutRepo: IAboutRepo

    @Injected
    private lateinit var mSettingRepo: ISettingRepo
}

打完收工?。。?/p>

其他

關于組件的初始化、 組件之間跳轉、 組件之間的通訊、 組件之間的回調等用法效果請運行 Demo 查看效果, 其用法請參考 Demo!!!

如果覺得有幫助, 歡迎 Star

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容