当前位置: 代码迷 >> Android >> AndroidEventBus V1.0.4版公布啦
  详细解决方案

AndroidEventBus V1.0.4版公布啦

热度:352   发布时间:2016-04-24 11:57:58.0
AndroidEventBus V1.0.4版发布啦

关注微信号:javalearns?? 随时随地学Java

或扫一扫

?

?

随时随地学Java

新版特性
?
支持Stickyandroid-study.com/pingtaikaifa/631.html">事件;
弱引用持有订阅者,无需手动unregister,避免内存泄露。
什么是Stickyandroid-study.com/pingtaikaifa/631.html">事件?
?
关于Stickyandroid-study.com/pingtaikaifa/631.html">事件有的同学可能不是很熟悉,Sticky的意思是粘性的。在Android开发中,Stickyandroid-study.com/pingtaikaifa/631.html">事件只指android-study.com/pingtaikaifa/631.html">事件消费者在android-study.com/pingtaikaifa/631.html">事件发布之后才注册的也能接收到该android-study.com/pingtaikaifa/631.html">事件的特殊类型。Android中就有这样的实例,也就是Sticky Broadcast,即粘性广播。正常情况下如果发送者发送了某个广播,而接收者在这个广播发送后才注册自己的Receiver,这时接收者便无法接收到刚才的广播,为此Android引入了StickyBroadcast,在广播发送结束后会保存刚刚发送的广播(Intent),这样当接收者注册完Receiver后就可以接收到刚才已经发布的广播。这就使得我们可以预先处理一些android-study.com/pingtaikaifa/631.html">事件,让有消费者时再把这些android-study.com/pingtaikaifa/631.html">事件投递给消费者。
?
AndroidEventBus也提供了这样的功能,有所不同是AndroidEventBus会存储所有的Stickyandroid-study.com/pingtaikaifa/631.html">事件,如果某个android-study.com/pingtaikaifa/631.html">事件在不需要再存储则需要手动进行移除。用户通过Sticky的形式发布android-study.com/pingtaikaifa/631.html">事件,而消费者也需要通过Sticky的形式进行注册,当然这种注册除了可以接收Stickyandroid-study.com/pingtaikaifa/631.html">事件之外和常规的注册功能是一样的,其他类型的android-study.com/pingtaikaifa/631.html">事件也会被正常处理。发布、接收Stickyandroid-study.com/pingtaikaifa/631.html">事件的步骤有如下几步 :
?
1、发布Stickyandroid-study.com/pingtaikaifa/631.html">事件;
?
1
2
EventBus.getDefault().postSticky("hello");

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

?
1
2
3
4
5
6
7
8
9
10
11
12
????public?class?MyReceiver {
????public?MyReceiver() {
????????EventBus.getDefault().registerSticky(this);
????}
?
????@Subscriber
????private?void?onStickyEvent(String info) {
????????System.out.println("接收到<a title="事件" href="http://www.<a title="android" href="http://www.android-study.com/pingtaikaifa/631.html">android</a>-study.com/pingtaikaifa/631.html">事件</a> : " + info);
????}
?
}
????
当在某个时刻构造MyReceiver时就会将MyReceiver对象以Sticky的形式注册到EventBus中,此时先前发布的”hello”android-study.com/pingtaikaifa/631.html">事件就会被MyReceiver对象接收到,因此就会执行onStickyEvent函数,在该函数中实现具体的逻辑即可。当然,不要忘了在某个时刻将MyReceiver注销,以弱引用的形式持有订阅者的功能还没有完成呐!整个过程就这样结束了~
?
Stickyandroid-study.com/pingtaikaifa/631.html">事件的运用场景
?
上文中我们简单讲述了Stickyandroid-study.com/pingtaikaifa/631.html">事件的基本使用步骤,这里我们以一个具体的示例来看看Stickyandroid-study.com/pingtaikaifa/631.html">事件在开发中的使用场景。
?
在开发过程中,我们经常需要在Activity之间传值,我们的做法就是将数据塞到Intent中,并且为每个数据设置一个key。当我们传递的数据是一个实体类时,我们的这个类还需要实现序列化接口,比如Parcelable或者Serializable。例如我们需要将一个用户对象传递到用户个人信息展示页面。我们的常规做法是这样的:
?
User.java类 :
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
????// 实体类实现序列化
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 =?newParcelable.Creator<User>() {
?
????????@Override
????????public?User createFromParcel(Parcel source) {
????????????return?new?User(source);
????????}
?
????????@Override
????????public?User[] newArray(int?size) {
????????????return?new?User[size];
????????}
????};
?}

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
????public?class?MainActivity?extends?Activity {
?
????// 某个点击<a title="事件" href="http://www.<a title="android" href="http://www.android-study.com/pingtaikaifa/631.html">android</a>-study.com/pingtaikaifa/631.html">事件</a>
????@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);
????}
}

在某个点击android-study.com/pingtaikaifa/631.html">事件的处理函数中我们通过Intent将数据传递给ProfileActivity。我们再看看ProfileActivity从Intent中取出数据的代码。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
????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,至此整个过程才算结束了。 大哥,我只是需要传个数据啊!何苦啊! 这种方式产生了很多的样板代码,也让逻辑变得更复杂,容易出错。我们再看看使用Stickyandroid-study.com/pingtaikaifa/631.html">事件的实现方式。 User.java类 :

?
1
2
3
4
5
6
7
8
9
10
11
12
????// 实体类实现序列化
public?class?User? {
????????String name ;
????????String phoneNum;
????????// 其他字段省略
?
????????public?User(String aName) {
????????????name = aName ;
????????}
?
????????// 代码省略
?}

首先User类不需要实现序列化接口,避免了那些样板代码。然后在MainActivity中直接将User对象作为Stickyandroid-study.com/pingtaikaifa/631.html">事件发布即可。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
????public?class?MainActivity?extends?Activity {
?
????// 某个点击<a title="事件" href="http://www.<a title="android" href="http://www.android-study.com/pingtaikaifa/631.html">android</a>-study.com/pingtaikaifa/631.html">事件</a>
????@Override
????public?void?onClick(View v) {
????????User aUser =?new?User("Mr.Simple");
????????aUser.phoneNum =?"123456";
????????// 其他数据
????????// 发布Sticky<a title="事件" href="http://www.<a title="android" href="http://www.android-study.com/pingtaikaifa/631.html">android</a>-study.com/pingtaikaifa/631.html">事件</a>
????????EventBus.getDefault().postSticky(aUser);
????????// 跳转到ProfileActivity页面
????????Intent intent =?new?Intent(this, ProfileActivity.class);
????????startActivity(intent);
????}
}

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
????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?receiveUser(User info){
?????????// 这里实现你的逻辑即可, info即为传递过来的User对象
????}
?
}
在ProfileActivity中我们将ProfileActivity自身作为订阅者注册到总线当中,此时ProfileActivity就会接收到上面发布的Stickyandroid-study.com/pingtaikaifa/631.html">事件,这个android-study.com/pingtaikaifa/631.html">事件对象就是User对象。此时就会触发ProfileActivity 中的receiveUser函数,info参数就是Stickyandroid-study.com/pingtaikaifa/631.html">事件的那个用户信息对象,在receiveUser中实现自己的逻辑即可。
?
是的!我们并没有在onDestory中对订阅者进行注销,也就是没有调用EventBus的unregister()函数,这就是最新版的特性之一,也是目前唯一不需要手动注销的android-study.com/pingtaikaifa/631.html">事件总线库。

关注微信号:javalearns?? 随时随地学Java

或扫一扫

?

?

随时随地学Java