Android模块化点滴-模块交互| 8月更文挑战

185 阅读2分钟

Module间的交互

  • EventBus。当EventBean非常多(一对一),一对多就会混乱不堪、难以维护;
  • 反射。发射维护成本高且容易出现@hide限制;
  • 隐式意图。维护成本高、需要维护Mainifest中的action
  • BroadCastReceiver 需要动态注册(7.0后),需求方发送广播。
  • 类加载。需要准确的全类名路劲,维护成本高。

类加载方式

//需要准确的全路径类名
val targetClass = Class.forName("com.loveqrc.user.UserMainActivity")
val intent = Intent(this, targetClass)
startActivity(intent)

全局Map记录信息

创建PathBean用于封装路径信息。

class PathBean {
    //跳转目标字符串缩写,如"user/UserMainActivity"
    var path: String? = null
    //跳转目标class
    var clazz: Class<*>? = null

    constructor() {}
    constructor(path: String, clazz: Class<*>) {
        this.path = path
        this.clazz = clazz
    }
}

属性path记录跳转目标字符串缩写,如user/UserMainActivity,属性clazz记录跳转目标class,如UserMainActivity::class.java

有了PathBean记录路径信息后,还需要一个RecordPathManager用于添加和查询。

object RecordPathManager {
    // key: 模块的名称,例如:user     value:模块下,对应所有的Activity路径信息
    private var groupMap: MutableMap<String, MutableList<PathBean>> = HashMap()

    /**
     * 将路径信息加入全局Map
     *
     * @param groupName 组名,如:"user"
     * @param pathName  路劲名,如:"UserMainActivity"
     * @param clazz     类对象,如:UserMainActivity::class.java
     */
    fun joinGroup(groupName: String, pathName: String?, clazz: Class<*>?) {
        var list = groupMap[groupName]
        if (list == null) {
            list = ArrayList()
            list.add(PathBean(pathName!!, clazz!!))
            groupMap[groupName] = list
        } else {
            groupMap[groupName] = list
        }
        groupMap[groupName] = list
    }

    /**
     * 根据组名和路径名获取类对象,达到跳转目的
     *
     * @param groupName 组名
     * @param pathName  路径名
     * @return 跳转目标的class类对象
     */
    fun getTargetClass(groupName: String, pathName: String): Class<*>? {
        val list = groupMap[groupName]
            ?: return null
        for (path in list) {
            if (pathName.equals(path.path, ignoreCase = true)) {
                return path.clazz
            }
        }
        return null
    }
}

有了RecordPathManager之后,那么就可以在Application创建时进行统一注册模块页面了

class MyApplication : Application() {

    override fun onCreate() {
        super.onCreate()
        RecordPathManager.joinGroup("user", "UserMainActivity", UserMainActivity::class.java)
    }
}

注册完成后,就可以通过RecordPathManager启动页面了。

val targetClass = RecordPathManager.getTargetClass("user", "UserMainActivity")
val intent = Intent(this, targetClass)
startActivity(intent)

总结

无论上面哪种都有hard code的感觉,不够智能,类加载方式,需求准确的类名,不能有错,加大维护难度,全局Map记录,需要一个一个手动的录入,当项目很大时,那么就要在Application中往RecordPathManager注册很多次。

有需求就会有解决方法,这时需要apt解决问题。