用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()
}
}
}
网友评论