当前位置: 首页 > news >正文

EventBus (四) Sticky事件

什么是Sticky事件?

关于Sticky事件有的同学可能不是很熟悉,Sticky的意思是粘性的。在Android开 发中,Sticky事件只指事件消费者在事件发布之后才注册的也能接收到该事件的特殊类型。Android中就有这样的实例,也就是Sticky Broadcast,即粘性广播。正常情况下如果发送者发送了某个广播,而接收者在这个广播发送后才注册自己的Receiver,这时接收者便无法接收到 刚才的广播,为此Android引入了StickyBroadcast,在广播发送结束后会保存刚刚发送的广播(Intent),这样当接收者注册完 Receiver后就可以接收到刚才已经发布的广播。这就使得我们可以预先处理一些事件,让有消费者时再把这些事件投递给消费者。

AndroidEventBus也提供了这样的功能,有所不同是AndroidEventBus会存储所有的Sticky事件,如果某个事件在不需 要再存储则需要手动进行移除。用户通过Sticky的形式发布事件,而消费者也需要通过Sticky的形式进行注册,当然这种注册除了可以接收 Sticky事件之外和常规的注册功能是一样的,其他类型的事件也会被正常处理。发布、接收Sticky事件的步骤有如下几步 :

1、发布Sticky事件;

EventBus.getDefault().postSticky("hello");

 

2、 某个时刻订阅者以Sticky的形式注册


public class MyReceiver {
    public MyReceiver() { EventBus.getDefault().registerSticky(this); } @Subscriber private void onStickyEvent(String info) { System.out.println("接收到事件 : " + info); } }

当在某个时刻构造MyReceiver时就会将MyReceiver对象以Sticky的形式注册到EventBus中,此时先前发布的”hello”事件就会被MyReceiver对象接收到,因此就会执行onStickyEvent函数,在该函数中实现具体的逻辑即可。当然,不要忘了在某个时刻将MyReceiver注销,以弱引用的形式持有订阅者的功能还没有完成呐!整个过程就这样结束了~

Sticky事件的运用场景

上文中我们简单讲述了Sticky事件的基本使用步骤,这里我们以一个具体的示例来看看Sticky事件在开发中的使用场景。

在开发过程中,我们经常需要在Activity之间传值,我们的做法就是将数据塞到Intent中,并且为每个数据设置一个key。当我们传递的数 据是一个实体类时,我们的这个类还需要实现序列化接口,比如Parcelable或者Serializable。例如我们需要将一个用户对象传递到用户个 人信息展示页面。我们的常规做法是这样的:

User.java类 :

// 实体类实现序列化
public class User implements Parcelable { String name ; String phoneNum; // 其他字段省略 public User(String aName) { name = aName ; } public User(Parcel in) { super(in); name = in.readString(); phoneNum = in.readString(); } // 代码省略 @Override public void writeToParcel(Parcel dest, int flags) { dest.writeString(name); dest.writeString(phoneNum); } public static final Parcelable.Creator<User> CREATOR = new Parcelable.Creator<User>() { @Override public User createFromParcel(Parcel source) { return new User(source); } @Override public User[] newArray(int size) { return new User[size]; } }; }

 

然后我们要在某个Activity中将这个用户数据传递给个人信息界面ProfileActivity。代码如下 :

public class MainActivity extends Activity { // 某个点击事件 @Override public void onClick(View v) { User aUser = new User("Mr.Simple"); aUser.phoneNum = "123456"; // 其他数据 Intent intent = new Intent(this, ProfileActivity.class); intent.putParcelable("user", aUser); startActivity(intent); } }

 

在某个点击事件的处理函数中我们通过Intent将数据传递给ProfileActivity。我们再看看ProfileActivity从Intent中取出数据的代码。

public class ProfileActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_profile); // 从Bundle中获取数据 Bundle extraBundle = getIntent().getExtras(); if (extraBundle != null) { User user = extraBundle.getParcelable("user"); } } }

 

OK,至此整个过程才算结束了。

大哥,我只是需要传个数据啊!何苦啊!
这种方式产生了很多的样板代码,也让逻辑变得更复杂,容易出错。我们再看看使用Sticky事件的实现方式。

User.java类 :

// 实体类实现序列化
public class User { String name ; String phoneNum; // 其他字段省略 public User(String aName) { name = aName ; } // 代码省略 }

 

首先User类不需要实现序列化接口,避免了那些样板代码。然后在MainActivity中直接将User对象作为Sticky事件发布即可。

public class MainActivity extends Activity { // 某个点击事件 @Override public void onClick(View v) { User aUser = new User("Mr.Simple"); aUser.phoneNum = "123456"; // 其他数据 // 发布Sticky事件 EventBus.getDefault().postSticky(aUser); // 跳转到ProfileActivity页面 Intent intent = new Intent(this, ProfileActivity.class); startActivity(intent); } }

最后我们看看ProfileActivity如何接收数据。

public class ProfileActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_profile); // 以Sticky的形式注册 EventBus.getDefault().registerSticky(this); } @Subscriber private void onStickyEvent(User info){ // 这里实现你的逻辑即可, info即为传递过来的User对象 } }

在ProfileActivity中我们将ProfileActivity自身作为订阅者注册到总线当中,此时ProfileActivity就会 接收到上面发布的Sticky事件,这个事件对象就是User对象。此时就会触发ProfileActivity 中的receiveUser函数,info参数就是Sticky事件的那个用户信息对象,在receiveUser中实现自己的逻辑即可。

是的!我们并没有在onDestory中对订阅者进行注销,也就是没有调用EventBus的unregister()函数,这就是最新版的特性之一,也是目前唯一不需要手动注销的事件总线库。

借鉴:http://blog.csdn.net/bboyfeiyu/article/details/46116357

相关文章:

  • Centos6.6搭建中文版本的Cacti监控
  • 模拟停车POJ(3505)
  • 翻页效果
  • HDU 1162 prime+邻接矩阵
  • 特殊二维数组的查找
  • win8 开发之旅(19) --足球游戏揭秘6
  • linux下sed基本用法详解
  • [翻译] UPCardsCarousel
  • Java编程的逻辑 (1) - 数据和变量
  • ABP源码分析三十二:ABP.SignalR
  • office2003 安装步骤及注意事项
  • 我的屌丝giser成长记-研一篇(下)
  • 本周活动
  • MapReduce的过程(2)
  • Android 双卡双待识别
  • 10个确保微服务与容器安全的最佳实践
  • ComponentOne 2017 V2版本正式发布
  • IDEA常用插件整理
  • iOS编译提示和导航提示
  • JavaScript 基础知识 - 入门篇(一)
  • JAVA多线程机制解析-volatilesynchronized
  • JS+CSS实现数字滚动
  • JS笔记四:作用域、变量(函数)提升
  • Linux Process Manage
  • Redis 懒删除(lazy free)简史
  • Sublime text 3 3103 注册码
  • vue从创建到完整的饿了么(18)购物车详细信息的展示与删除
  • webpack项目中使用grunt监听文件变动自动打包编译
  • XForms - 更强大的Form
  • 基于Dubbo+ZooKeeper的分布式服务的实现
  • 如何在 Tornado 中实现 Middleware
  • 移动端唤起键盘时取消position:fixed定位
  • 中文输入法与React文本输入框的问题与解决方案
  • Android开发者必备:推荐一款助力开发的开源APP
  • 移动端高清、多屏适配方案
  • !$boo在php中什么意思,php前戏
  • ###STL(标准模板库)
  • (02)vite环境变量配置
  • (10)Linux冯诺依曼结构操作系统的再次理解
  • (k8s中)docker netty OOM问题记录
  • (附源码)springboot太原学院贫困生申请管理系统 毕业设计 101517
  • (三)docker:Dockerfile构建容器运行jar包
  • (十八)用JAVA编写MP3解码器——迷你播放器
  • (十二)springboot实战——SSE服务推送事件案例实现
  • (实战篇)如何缓存数据
  • (太强大了) - Linux 性能监控、测试、优化工具
  • (一)spring cloud微服务分布式云架构 - Spring Cloud简介
  • .Net Attribute详解(上)-Attribute本质以及一个简单示例
  • .NET I/O 学习笔记:对文件和目录进行解压缩操作
  • .NET微信公众号开发-2.0创建自定义菜单
  • .skip() 和 .only() 的使用
  • .xml 下拉列表_RecyclerView嵌套recyclerview实现二级下拉列表,包含自定义IOS对话框...
  • @html.ActionLink的几种参数格式
  • [ element-ui:table ] 设置table中某些行数据禁止被选中,通过selectable 定义方法解决
  • [ HTML + CSS + Javascript ] 复盘尝试制作 2048 小游戏时遇到的问题