什么是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

EventBus (四) Sticky事件的更多相关文章

  1. 【第一篇】学习 android 事件总线androidEventbus之sticky事件的传递

    最近再看eventbus相关代码,首先从使用开始,后期再从源码角度分析eventbus.使用Demo后期公布到github上去. 使用的框架地址:https://github.com/bboyfeiy ...

  2. 由浅入深了解EventBus:(四)

    事件注册 在EventBus3.0框架中订阅者对事件进行注册/订阅是通过EventBus类中的register方法来实现的,register的方法参数就是我们的订阅者的实例; public void ...

  3. EventBus的粘性事件

    下午赶去公司解决了电台业务首次语音搜台后(用到服务,但只出一个独立的Activity,主界面并没有打开)不能听歌识曲的问题. 排查到最后,去识别的消息确实是发出去了,但是却没有收到,没有收到消息当然不 ...

  4. MVVM设计模式和WPF中的实现(四)事件绑定

    MVVM设计模式和在WPF中的实现(四) 事件绑定 系列目录: MVVM模式解析和在WPF中的实现(一)MVVM模式简介 MVVM模式解析和在WPF中的实现(二)数据绑定 MVVM模式解析和在WPF中 ...

  5. HTML 事件(四) 模拟事件操作

    本篇主要介绍HTML DOM中事件的模拟操作. 其他事件文章 1. HTML 事件(一) 事件的介绍 2. HTML 事件(二) 事件的注册与注销 3. HTML 事件(三) 事件流与事件委托 4.  ...

  6. MVVM设计模式和在WPF中的实现(四) 事件绑定

    系列目录: MVVM模式解析和在WPF中的实现(一)MVVM模式简介 MVVM模式解析和在WPF中的实现(二)数据绑定 MVVM模式解析和在WPF中的实现(三)命令绑定 MVVM模式解析和在WPF中的 ...

  7. jQuery中四种事件监听的区别

    原文链接:点我 我们知道jquery提供了四种事件监听方式,分别是bind.live.delegate.on,下面就分别对这四种事件监听方式分析. 已知有4个列表元素: 列表元素1 列表元素2 列表元 ...

  8. 【Shashlik.EventBus】.NET 事件总线,分布式事务最终一致性

    [Shashlik.EventBus].NET 事件总线,分布式事务最终一致性 简介 github https://github.com/dotnet-shashlik/shashlik.eventb ...

  9. OneAlert 入门(四)——事件分派和通知必达

    OneAlert 是国内首个 SaaS 模式的云告警平台,集成国内外主流监控/支撑系统,实现一个平台上集中处理所有 IT 事件,提升 IT 可靠性.有了 OneAlert,你可以更快更合理地为事件划分 ...

随机推荐

  1. CSS基础选择器温故-1

    1.基本选择器语法 2.浏览器兼容性:浏览器对基本选择器都是一路绿灯通行,可以放心使用. 3.通配选择器:选择所有元素,也可以选择某个元素下的所有元素 (1)选择所有元素: *{margin: 0;p ...

  2. Angular框架

    Angular 框架 Angular介绍 库和框架的区别 jQuery:库 库一般都是封装了一些常用的方法 自己手动去调用这些方法,来完成我们的功能 code $('#txt').val('我是小明' ...

  3. angularjs作用域

    作用域(scope)①是构成AngularJS应用的核心基础,在整个框架中都被广泛使用,因此了解它如何工作是非常重要的.应用的作用域是和应用的数据模型相关联的,同时作用域也是表达式执行的上下文.$sc ...

  4. GridView1_RowDataBound解决限制字段显示长度用"..."显示ToolTip

    ToolTip: // // 摘要: // 获取或设置当鼠标指针悬停在 Web 服务器控件上时显示的文本. // // 返回结果: // 当鼠标指针悬停在 Web 服务器控件上时显示的文本.默认值为 ...

  5. 获取经过跳转后的url地址

    粗略一算,不写code已经好几个月了. 昨日受兄弟所托,为他写了一个小小的程序. 程序功能: 自动获取跳转后的Url地址 如下图所示: (newUrl.txt为转换后的地址信息...) 实现过程: 每 ...

  6. Java中的守护线程和非守护线程(转载)

    <什么是守护线程,什么是非守护线程> Java有两种Thread:"守护线程Daemon"(守护线程)与"用户线程User"(非守护线程). 用户线 ...

  7. iOS设计模式之迭代器模式

    迭代器模式 基本理解 迭代器模式(Iterrator):提供一个方法顺序访问一个聚合对象中的各个元素,而又不暴露该元素的内部表示. 当你访问一个聚合对象,而且不管这些对象是什么都需要遍历的时候,你就应 ...

  8. Android群英传笔记系列三 view的自定义:实现一个模拟下载

    1.实现效果:动态显示进度(分别显示了整个的动态改变的过程,然后完成后,弹出一个对话框)       2.实现过程:可以分为绘制一个圆,圆弧和文本三部分,然后在MainAcitivity中通过线程模拟 ...

  9. iOS 删除 Main.storyboard 和 LaunchScreen.storyboard

    第一步: 右键选中Main.storyboard —- delete —— Move to Trash LaunchScreen同理 第二步 点击工程名,就是最顶级目录 右侧出现general选项卡 ...

  10. iOS-协议与代理<转>

    代理,又称委托代理(delegate),是iOS中常用的设计一种模式.顾名思义,它是把某个对象要做的事情委托给别的对象去做.那么别的对象就是这个对象的代理,代替它来打理要做的事.反映到程序中, 首先要 ...