kotlin EventBus

作者: 折剑游侠 | 来源:发表于2020-04-08 16:43 被阅读0次

    用kotlin简单的实现一下EventBus,直接上代码。

    • 事件订阅方法注解Subscribe
    //事件订阅注解
    @Target(AnnotationTarget.FUNCTION)
    @Retention(value = AnnotationRetention.RUNTIME)
    annotation class Subscribe(val threadModel: ThreadModel = ThreadModel.POSTING)
    
    • 订阅方法运行所在线程枚举类
    enum class ThreadModel {
        //同事件发起线程
        POSTING,
        //主线程
        MAIN,
        //子线程
        ASYNC
    }
    
    • 订阅方法实体类
    class SubscribeMethod(
        //订阅方法
        var method: Method,
        //线程模式
        var threadModel: ThreadModel,
        //参数类型
        var eventType: Class<*>
    )
    
    • AndroidBus单例
    object AndroidBus {
        //订阅者和事件缓存map
        private val map: MutableMap<Any, List<SubscribeMethod>> = mutableMapOf()
        private val handler = Handler(Looper.getMainLooper())
        private val executors = Executors.newCachedThreadPool()
    
        /**
         * 注册
         * @param subscribe
         */
        fun register(subscribe: Any) {
            var list = map[subscribe]
            if (list == null) {
                list = getSubscribeMethods(subscribe)
                map[subscribe] = list
            }
        }
    
        /**
         * 取消注册
         * @param subscribe
         */
        fun unRegister(subscribe: Any) {
            val list = map[subscribe]
            if (list != null) {
                map.remove(subscribe)
            }
        }
    
        /**
         * 获取订阅方法
         * @param subscribe
         */
        private fun getSubscribeMethods(subscribe: Any): List<SubscribeMethod> {
            val list: MutableList<SubscribeMethod> = mutableListOf()
            val clazz = subscribe.javaClass
            val name = clazz.name
            if (name.startsWith("java.") ||
                name.startsWith("javax.") ||
                name.startsWith("android.") ||
                name.startsWith("androidx.")
            ) {
                return emptyList()
            }
            val declaredMethods = clazz.declaredMethods
            declaredMethods.forEach {
                val annotation = it.getAnnotation(Subscribe::class.java) ?: return@forEach
                val parameterTypes = it.parameterTypes
                if (parameterTypes.size != 1) {
                    throw RuntimeException("AndroidBus只能接收一个参数")
                }
                val threadModel = annotation.threadModel
                val subscribeMethod = SubscribeMethod(
                    it,
                    threadModel,
                    parameterTypes[0]
                )
                list.add(subscribeMethod)
            }
            return list
        }
    
        /**
         * 发送事件
         * @param bean
         */
        fun post(bean: Any) {
            map.forEach {
                val list = it.value
                list.forEach { subscribeMethod ->
                    if (subscribeMethod.eventType.isAssignableFrom(bean::class.java)) {
                        when (subscribeMethod.threadModel) {
                            ThreadModel.POSTING -> {
                                callback(subscribeMethod, it.key, bean)
                            }
                            ThreadModel.MAIN -> {
                                if (Looper.myLooper() == Looper.getMainLooper()) {
                                    callback(subscribeMethod, it.key, bean)
                                } else {
                                    handler.post {
                                        callback(subscribeMethod, it.key, bean)
                                    }
                                }
                            }
                            ThreadModel.ASYNC -> {
                                if (Looper.myLooper() != Looper.getMainLooper()) {
                                    callback(subscribeMethod, it.key, bean)
                                } else {
                                    executors.execute {
                                        callback(subscribeMethod, it.key, bean)
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    
        /**
         * 回调
         * @param subscribeMethod 注册方法
         * @param subscribe 订阅类
         * @param bean 事件
         */
        private fun callback(subscribeMethod: SubscribeMethod, subscribe: Any, bean: Any) {
            val method = subscribeMethod.method
            method.invoke(subscribe, bean)
        }
    }
    

    在Activity.onCreate()中调用register()注册,onDestroy()中调用unRegister()取消注册。

    定义事件订阅方法,触发事件时调用post()。

    class MainActivity : AppCompatActivity() {
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_main)
    
            AndroidBus.register(this)
    
            tvMain.setOnClickListener {
                val intent = Intent(this, SecondActivity::class.java)
                startActivity(intent)
            }
        }
    
        @Subscribe
        fun call(str: String) {
            if (str == "posting") tvMain.text = "posting"
        }
    
        override fun onDestroy() {
            super.onDestroy()
            AndroidBus.unRegister(this)
        }
    }
    
    class SecondActivity : AppCompatActivity() {
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_second)
    
            btSecond.setOnClickListener {
                AndroidBus.post("posting")
                onBackPressed()
            }
        }
    }
    

    相关文章

      网友评论

        本文标题:kotlin EventBus

        本文链接:https://www.haomeiwen.com/subject/fmgtmhtx.html