安卓开发笔记——探索EventBus(转)
1、关于EventBus:
组件通讯在Android开发中是不可避免的,随着业务需求的复杂化,代码中需要我们去处理的业务逻辑难度也不断增大。例如多个Fragment之间的数据传递,Service与Activity、Fragment之间的通讯,BroadCast与Activity、Fragment之间的通讯,各种startActivityForResult的使用,繁杂的操作令我们所厌倦,在GitHub上找了下解决方案,发现了一个不错的开源库EventBus,相信很多做过Android开发的朋友都或多或少对此有所了解。
EventBus是一款针对Android优化的发布/订阅事件总线。主要功能是替代Intent,Handler,BroadCast在Fragment,Activity,Service,线程之间传递消息.优点是开销小,代码更优雅。以及将发送者和接收者解耦。
这是EventBus在GitHub上的开源库地址:https://github.com/greenrobot/EventBus
EventBus的大体关系是这样的:订阅者(Subscriber)通过订阅事件(Event)到总线,事件发布者(Publisher)发布事件(Event)到总线被订阅者(Subscriber)接收,其实说白了就是软件设计模式里的观察者模式。EventBus在使用的时候就是在合适的地方发布一个事件,使得注册了该事件接收的对象就可以收到通知,进行相应的操作。
2、初探EventBus:
文绉绉的文字描述令人厌烦,直接上代码说话吧,先来看下要实现的效果:
看似很简单的效果,点击按钮跳转界面,利用Intent发送一个消息,然后TextView接收显示。这是传统上的做法,如果真是这样做,那么写这篇文章的就完全没意义了。其实这里就是利用到了EventBus,并没有用到Intent来传递消息。
先来看下具体的代码(记得添加EventBus的引用),然后我再分部来解析:
1 package com.lcw.rabbit.eventbusdemo.eventbusdemo; 2 3 import android.content.Intent; 4 import android.os.Bundle; 5 import android.support.v7.app.AppCompatActivity; 6 import android.view.View; 7 import android.widget.Button; 8 import android.widget.TextView; 9 10 import de.greenrobot.event.EventBus; 11 12 public class MainActivity extends AppCompatActivity { 13 14 private Button mBt_1; 15 private TextView mTv_1; 16 17 @Override 18 protected void onCreate(Bundle savedInstanceState) { 19 super.onCreate(savedInstanceState); 20 setContentView(R.layout.activity_main); 21 //注册绑定EventBus 22 EventBus.getDefault().register(this); 23 24 initView(); 25 initAction(); 26 27 } 28 29 private void initAction() { 30 mBt_1.setOnClickListener(new View.OnClickListener() { 31 @Override 32 public void onClick(View v) { 33 startActivity(new Intent(MainActivity.this, SecondActivity.class)); 34 } 35 }); 36 } 37 38 private void initView() { 39 mBt_1 = (Button) findViewById(R.id.bt_1); 40 mTv_1 = (TextView) findViewById(R.id.tv_info1); 41 } 42 43 44 //接收所订阅的消息 45 public void onEventMainThread(MyEvent myEvent) { 46 if (myEvent.getInfo()!=null) { 47 mTv_1.setText(myEvent.getInfo()); 48 } 49 50 } 51 52 53 @Override 54 protected void onDestroy() { 55 super.onDestroy(); 56 //解绑EventBus 57 EventBus.getDefault().unregister(this); 58 } 59 }
MainActivity.java
1 package com.lcw.rabbit.eventbusdemo.eventbusdemo; 2 3 import android.os.Bundle; 4 import android.support.v7.app.AppCompatActivity; 5 import android.view.View; 6 import android.widget.Button; 7 import android.widget.Toast; 8 9 import de.greenrobot.event.EventBus; 10 11 public class SecondActivity extends AppCompatActivity { 12 13 private Button mBt_2; 14 15 @Override 16 protected void onCreate(Bundle savedInstanceState) { 17 super.onCreate(savedInstanceState); 18 setContentView(R.layout.activity_second); 19 initView(); 20 initAction(); 21 22 } 23 24 private void initAction() { 25 mBt_2.setOnClickListener(new View.OnClickListener() { 26 @Override 27 public void onClick(View v) { 28 Toast.makeText(SecondActivity.this,"消息已发送",Toast.LENGTH_SHORT).show(); 29 EventBus.getDefault().post(new MyEvent("我是被发送过来的消息")); 30 31 } 32 }); 33 } 34 35 private void initView() { 36 mBt_2 = (Button) findViewById(R.id.bt_2); 37 } 38 39 40 }
SecondActivity.java
1 package com.lcw.rabbit.eventbusdemo.eventbusdemo; 2 3 /** 4 * Created by Lichenwei 5 * Date: 2015-10-11 6 * Time: 18:23 7 */ 8 public class MyEvent { 9 10 private String info; 11 12 public MyEvent(String info) { 13 this.info = info; 14 } 15 16 public String getInfo() { 17 return info; 18 } 19 20 public void setInfo(String info) { 21 this.info = info; 22 } 23 }
MyEvent
上面的代码很简单,这里只是抛砖引玉并不做太多复杂的操作,大家可以根据自己的项目需求来添加对应的代码。
3、解析代码:
1、注册EventBus:
在添加EventBus的引用后,我们就可以对任意类进行注册绑定和解绑EventBus事件,注册方法和反注册方法很简单,在上面的代码中就可以看出来了,分别是register和unregister,这里的EventBus.getDefault是获取到EventBus实例的意思(单例)。
1 //注册绑定EventBus 2 EventBus.getDefault().register(this); 3 //解绑EventBus 4 EventBus.getDefault().unregister(this);
2、EventBus事件:
EventBus很灵活,它对事件不进行任何的限制,也不需要继承或者实现任何类或者接口,可以是任意类型的实体类,好比上面代码提到的MyEvent。
3、EventBus事件发布者:
有了事件之后,我们就可以对事件进行发布,然后可以被订阅这个事件的所有订阅者所接收。发送事件很简单,有两种方法post与postSticky:
1 //立即发送事件 2 EventBus.getDefault().post(Object event); 3 //延迟发送事件 4 EventBus.getDefault().postSticky(Objet event);
4、EventBus事件订阅者:
EventBus的事件订阅者可以是任何已经进行注册EventBus的类,订阅者的数量是没有上限的(很重要,下文会提到),这里的订阅有4种方法,这里都是由onEvent开头的,有着一定的区别:
1、onEvent:
如果使用onEvent作为订阅函数,那么该事件在哪个线程发布出来的,onEvent就会在这个线程中运行,也就是说发布事件和接收事件线程在同一个线程。使用这个方法时,在onEvent方法中不能执行耗时操作,如果执行耗时操作容易导致事件分发延迟。 2、onEventMainThread:
如果使用onEventMainThread作为订阅函数,那么不论事件是在哪个线程中发布出来的,onEventMainThread都会在UI线程中执行,接收事件就会在UI线程中运行,这个在Android中是非常有用的,因为在Android中只能在UI线程中跟新UI,所以在onEvnetMainThread方法中是不能执行耗时操作的。 3、onEventBackground:
如果使用onEventBackgrond作为订阅函数,那么如果事件是在UI线程中发布出来的,那么onEventBackground就会在子线程中运行,如果事件本来就是子线程中发布出来的,那么onEventBackground函数直接在该子线程中执行。 4、onEventAsync:
使用这个函数作为订阅函数,那么无论事件在哪个线程发布,都会创建新的子线程在执行onEventAsync。
1 public void onEvent(Object event) {} 2 public void onEventMainThread(Object event) {} 3 public void onEventBackgroundThread(Object event) {} 4 public void onEventAsync(Object event) {}
介绍完EventBus里的所有角色后,我们来理一理订阅/被订阅流程:
首先,要想成为事件订阅者需要先对EventBus进行注册绑定,然后在本类需要去写一个以onEvent开头的方法来接收处理消息事件,再来我们需要一个自定义的事件可以让事件的发布者发布,让事件的订阅者接收。事件的发布可以通过post方法或者是postSticky方法发布。
4、EventBus所带来的一些方便之处:
EventBus是一款针对Android优化的发布/订阅事件总线。主要功能是替代Intent,Handler,BroadCast在Fragment,Activity,Service,线程之间传递消息.优点是开销小,代码更优雅。以及将发送者和接收者解耦。这是我们在文章开头所介绍过的,这里就不多说了,说几个在实际开发中所运用到的地方。
例如:
1、当某个页面的某些值发生变化的时候,需要去同时去更改多个页面相对应的值,这时候只要这些类注册订阅了该事件,那么我们就可以很轻松通过post发送消息来进行通讯。
2、某些时候,我们并不希望发布出来的Event立即被消费掉,而是等到时机成熟。比如说,在一个详情页点赞之后,产生一个事件,这个事件并不立即被消费,而是等用户退出详情页回到商品列表之后,接收到该事件,然后刷新Adapter等。其实这就是之前我们用startActivityForResult和onActivityResult做的事情。这里我们就可以利用postSticky来实现这样的机制。
总之,EventBus极大的减轻了我们各种组件之间的通讯复杂度,也大大减少了使用ActivityForResult的麻烦。真实值得极力推荐。
5、理解EventBus
从源码中我们可以知道,当我们在类中注册绑定EventBus的时候,它会去扫描当前类并记录下所有已onEvent开头的方法,存放在一个Map<Key,Value>中,在事件通过post发布之后,EventBus会根据post中实参的类型,去Map中查找对应的方法,并找到了对应的Thread,最终利用Java的反射机制去执行我们的方法。
onEventMainThread表示这个方法会在UI主线程执行。
onEventPostThread表示这个方法会在当前发布事件的线程中执行。
BackgroundThread表示如果在非UI主线程发布的事件,则直接执行,和发布在同一个线程中。如果在UI线程发布的事件,则加入后台任务队列,使用线程池一个接一个调用。
Async 加入后台任务队列,使用线程池调用,注意没有BackgroundThread中的一个接一个。
http://www.cnblogs.com/lichenwei/p/4873249.html
安卓开发笔记——探索EventBus(转)相关推荐
- 安卓开发笔记——自定义广告轮播Banner(实现无限循环)
关于广告轮播,大家肯定不会陌生,它在现手机市场各大APP出现的频率极高,它的优点在于"不占屏",可以仅用小小的固定空位来展示几个甚至几十个广告条,而且动态效果很好,具有很好的用户& ...
- [安卓开发笔记二]android Studio通过jni调用C++代码
[安卓开发笔记二]android Studio通过jni调用C++代码 16/12/11 更新 此博客基于安卓android studio 1.5所写,现在已经有了android studio2.2的 ...
- [安卓开发笔记一]Android开发配置opencv环境超详细教程
[安卓开发笔记一]Android开发配置opencv环境超详细教程 [更新于 2022年4月] 再次提醒,建议现在看到这篇文章的,仅仅把此文做一个流程参考,4年前android studio就使用cm ...
- 安卓开发艺术探索总结
2019.1.11到2019.2.11历时一个月,这本书还算比较详细看完了,虽然说出版时间比较早,里面一些技术没有紧跟当前,这本书主要是教会我们的是安卓思想方面,还有对源码的分析,等等其他方面,这本书 ...
- 安卓开发笔记——打造属于自己的博客园APP(一)
最近事情比较多,博客更新又落下了,平时有个习惯,喜欢睡前看看博客园里博友的文章,但一直感觉APP市场上下载下来的博客园客户端用起来并不是很舒服,近来发现博客园也有对外开放的数据接口,所以打算自己写个博 ...
- 安卓开发艺术探索!各种风格的Android面试题进来了解一下,含爱奇艺,小米,腾讯,阿里
上周喜提oppo面试offer,本人在深圳,有4年多的Android项目经验,普通本科学历. 面试是相互相在,OPPO给我的印象确实如其核心价值观所说:本分. 一面.部长面和HR面都蛮顺利(一千个人可 ...
- 安卓开发笔记-UI设计的概念
本文是哔哩哔哩上 安卓开发教程 的笔记 UI的概念: 就是用户界面的意思 ① View 下面是官方的翻译 This class represents the basic building block ...
- 安卓开发笔记(二十六):Splash实现首页快速开屏功能
我们在进行安卓开发的时候,首页开有两种方式,一种是利用handler将一个活动进行延时,时间到达之后软件则会跳转到第二个活动当中.而另一种方法则是更加常用的方法,利用splash实现首页的快速开屏,这 ...
- 安卓开发笔记(十一)—— 方向传感器,实现摇一摇动画音效,GPS定位
中山大学数据科学与计算机学院本科生实验报告 (2018年秋季学期) 项目源码:Github传送门 一.实验题目 第十六周任务 传感器 第十六周实验目的 学会使用加速度传感器 学会使用地磁传感器 学会获 ...
- 安卓开发笔记(十二)—— 基于百度地图SDK完成地图中心定位,marker转向,动态定位
中山大学数据科学与计算机学院本科生实验报告 (2018年秋季学期) 项目源码:Github传送门 第十七周任务 一.实验题目 地图 第十七周实验目的 接入百度地图API 掌握少量的百度地图API接口 ...
最新文章
- OSC源创会往期图文回顾链接地址收藏
- 深度隐式表达:为什么不用mesh,点云,体素等表示方法?
- 1、C++招聘笔试--C++中的C
- Scrapy 扩展中间件: 同步/异步提交批量 item 到 MySQL
- ABAP和Java SpringBoot的单元测试
- 蒙特卡洛方法_基本理论-蒙特卡洛方法与定积分
- .Net微服务实战之技术选型篇
- ansible---基础
- .rdlc 文件设置方向_在Word里面怎么设置把字竖着打出来?
- 微软官方Windows主题 英国之美 高分辨率的壁纸
- uva 111 History Grading(最长公共子序列)
- (93)FPGA模块例化传递参数(defparam)
- toolchain安装教程支持_Xilinx交叉编译工具链安装步骤
- mysql自建云盘_使用nextcloud自建私人云盘
- 如何使用Selenium-Grid
- 问学计算机的同学买什么电脑,学生用的笔记本电脑什么样的好
- [每日一氵]索引变量要提前拿出来或者注意顺序
- k8s出现问题导致cpu使用率过高
- 机器人运动规划技术介绍
- h5页面生成图片分享到微信js_微信端h5页面如何调用分享页面的接口