Android学些-页面之间的数据传递(EventBus)

163 阅读2分钟

引入三方库

implementation 'org.greenrobot:eventbus:3.3.1'

在需要接收数据的 A 页面

//注册EventBus
override fun onStart() {
    super.onStart()
    println("---------------------onStart---------------------")
    if (!EventBus.getDefault().isRegistered(this)){
        EventBus.getDefault().register(this)
    }
}
//注销EventBus
override fun onDestroy() {
    super.onDestroy()
            EventBus.getDefault().unregister(this);
    println("---------------------onDestroy---------------------")
}

在需要返回数据的 B 页面

val savedUri = Uri.fromFile(photoFile)
EventBus.getDefault().post(savedUri)

然后再 A 页面

@Subscribe(threadMode = ThreadMode.MAIN)
fun onUri(event:Uri){
    this.event = event
}

对于iOS开发人员来说很神奇,不理解怎么做到的。

大概了解了一下原理:

d901a67fe41a4e8b86e5244bd92d972a.png (图片来至于网络)

1.通过反射遍历注册对象的方法,获取其中带有@Subscribe标签的方法并且放在一个列表中,最后以注册对象为key,@Subscribe的方法列表作为value放在HashMap中。
2.在 EventBus.getDefault().post(event) 发送事件的时候,在hashMap中查找注册了该event的多有对象,并执行对应的事件(event)接收方法。

注意点:需要自己注册和反注册,如果忘了反注册就会导致内存泄漏

关于 EventBus的线程模式。

也就是这里: @Subscribe(threadMode = ThreadMode.MAIN)

1、PostThread

事件的处理在和事件的发送在相同的进程,所以事件处理时间不应太长,不然影响事件的发送线程。

2、MainThread

事件的处理会在UI线程中执行。事件处理时间不能太长。

3、BackgroundThread

如果事件是在UI线程中发布出来的,那么事件处理就会在子线程中运行,如果事件本来就是子线程中发布出来的,那么事件处理直接在该子线程中执行。所有待处理事件会被加到一个队列中,由对应线程依次处理这些事件,如果某个事件处理时间太长,会阻塞后面的事件的派发或处理。

4、Async

事件处理会在单独的线程中执行,主要用于在后台线程中执行耗时操作,每个事件会开启一个线程。