EventBus(笔记)

news/2024/7/7 5:33:17 标签: eventbus, android, handler, thread

EventBus(3.0):

是什么?

EventBus is a publish/subscribe event bus optimized for Android.
(EventBus是一款针对Android优化的发布/订阅事件总线。主要功能是替代Intent,Handler,BroadCast在Fragment,Activity,Service,线程之间传递消息.优点是开销小,代码更优雅。以及将发送者和接收者解耦。)


如何做(Android Studio)?

1. compile 'org.greenrobot:eventbus:3.0.0'

2. 注册和反注册EventBus,将它们写在Activity或Fragment的生命周期里

 @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        bt_main = (Button) findViewById(R.id.bt_main);
        tv_main = (TextView) findViewById(R.id.tv_main);

        //注册
        EventBus.getDefault().register(this);

        bt_main.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent();
                intent.setClass(MainActivity.this , SecondActivity.class);
                startActivity(intent);
            }
        });
    }
    
    @Override
    protected void onDestroy() {
        super.onDestroy();
        //取消注册
        EventBus.getDefault().unregister(this);
    }

3.声明订阅方法(名称可自起,3.0之后不需要固定的onEvent开头的命名,根据@Subscribe和ThreadMode来判断):

要加@Subscribe注解和模式说明

 @Subscribe (threadMode = ThreadMode.MAIN)
    public void helloMain(FirstEvent firstEvent){
        
    }

4.post

 EventBus.getDefault().post(event);


ThreadMode模式说明(共四种):

1.ThreadMode.POSTING(原onEvent)

这是个默认的模式,订阅者将会在同一个线程里被声明。由于它避免线程切换完全,因此建议做些简单的并且在短时间能完成的任务。

" This ThreadMode implies the least overhead because it avoids thread switching completely. Thus this is the recommended mode for simple tasks that are known to complete is a very short time without requiring the main thread. Event handlers using this mode should return quickly to avoid blocking the posting thread, which may be the main thread. "

@Subscribe(threadMode = ThreadMode.POSTING) 
public void onMessage(MessageEvent event) {
    log(event.message);
}


2.ThreadMode.MAIN(原onEventMainThread)

订阅者将会在UI主线程里被声明,并且在该线程里应该做返回快速地操作,避免主线程阻塞。

" If the posting thread is the main thread, event handler methods will be called directly (synchronously like described for ThreadMode.POSTING). Event handlers using this mode must return quickly to avoid blocking the main thread.  "

@Subscribe(threadMode = ThreadMode.MAIN)
public void onMessage(MessageEvent event) {
    textField.setText(event.message);
}


3.ThreadMode.BACKGROUND(原onEvnetBackground)

如果发布的线程不是主线程,则它将会被直接声明为跟原来一样的线程;如果发布的线程为主线程,则EventBus将会通过一个独立的后台线程给该线程,并按照顺序来分发它的所有事件。

"If posting thread is not the main thread, event handler methods will be called directly in the posting thread. If the posting thread is the main thread, EventBus uses a single background thread that will deliver all its events sequentially. Event handlers using this mode should try to return quickly to avoid blocking the background thread."

@Subscribe(threadMode = ThreadMode.BACKGROUND)
public void onMessage(MessageEvent event){
    saveToDisk(event.message);
}


4.ThreadMode.ASYNC(原onEventAsync)

该模式主要是用于一些需要耗时地线程操作,像网络请求,它一直都是独立于主线程和posting线程。要避免同时触发大量的长时间的处理方法来限制并发线程。EventBus会使用一个线程池来高效地复用那些完成了异步事件处理程序的通知线程。

" This is always independent from the posting thread and the main thread. Posting events never wait for event handler methods using this mode. Event handler methods should use this mode if their execution might take some time, e.g. for network access. Avoid triggering a large number of long running asynchronous handler methods at the same time to limit the number of concurrent threads. EventBus uses a thread pool to efficiently reuse threads from completed asynchronous event handler notifications. "

@Subscribe(threadMode = ThreadMode.ASYNC)
public void onMessage(MessageEvent event){
    backend.send(event.message);
}

附小点:

原以为当一个EventBus post一个信息出来后只有一个会被接收到,但在多个fragment里的时候却发现会被多个同时收到,结果导致在做例如支付的时候发起了多个支付,所以这个还是要注意一下。

要注意EventBus的生命周期的调用情况,即该EventBus所处的Activity还没有被创建时,它是不会收到的;当然EventBus在所处的Activity的生命周期里被反注册掉,也同样收不到。所以当你在OneActivity想post给TwoActivity的时候,你需要先测试下它是否真的能起作用。



参考和扩展:

Android解耦库EventBus的使用和源码分析

EventBus: Events for Android (推荐)

EventBus使用详解(一)——初步使用EventBus

android 初识EventBus (推荐)

Android 中 EventBus 的使用(2):缓存事件

Why you should avoid using an event bus   为什么你应该停止使用EventBus(翻译)


http://www.niftyadmin.cn/n/1149573.html

相关文章

ViewStub(笔记)

今天在对项目做优化的时候,了解到了一个控件叫ViewStub。 主要的背景是在一般情况下,在一个布局里,我们对于里面的某部分的布局需要进行隐藏的操作,那么我们会采用View.INVISIBLE或是View.GONE。但它有个缺点就是太过于耗费内存了…

adb 环境配置 常用命令 总结

配置环境变量右键我的电脑 -> 属性 -> 高级 -> 环境变量 -> Path在Path中添加Android SDK安装路径中 adb.exe 的路径,例如【\sdk\platform-tools】,注意用【;】分号隔开。另外,最好也将【\sdk\platforms】目录添加进去。常用ADB命…

RecyclerView(笔记)

写在前面 ListView早些时候还没用熟,后来就出了个RecyclerView,怀着好奇心和贪图所谓的“方便”,就对ListView嗤之以鼻,也不太知道它的使用方法了。现在也懒得回去重新看,就直接对RecyclerView下手了。 记录下自己对这…

RecyclerView分割线之RecyclerView.ItemDecoration的理解(笔记)

今天对RecyclerView.ItemDecoration做了蛮多的理解,赶紧记下来,一直在思考分割线与item间的关系,后来模仿着做了很多的调整测试,才大概弄懂了。 这是一个分割线的绘制,通过multRecyclerView.addItemDecoration(new It…

shell---算术运算

shell中的赋值和操作默认都是字符串处理,1、错误方法举例a)var11echo $var输出的结果是11,悲剧,呵呵 b)var1var$var1echo $var输出结果是11,依然悲剧,呵呵 2、正确方法1)使用letvar1let "var1"echo $var输出…

关于mybatis的org.apache.ibatis.binding.BindingException: Invalid bound statement (not found):

2019独角兽企业重金招聘Python工程师标准>>> 关于mybatis的org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): 前言 今天遇到一个很郁闷的错误:org.apache.ibatis.binding.BindingException: Invalid bound statement…

Android之高德地图(一)(笔记)

今天接入了高德地图,想着大概半年前做高德地图的时候,完全看不懂代码,在那里看着官方的东西到凌晨两点还是看不懂,最后只能直接去复制别人的代码来用。虽然成功了,但是一直不知道为什么,而且那只是简简单单…