您的位置:首页 > 移动开发 > Android开发

Android进阶之路 - EventBus的理解使用

2017-06-10 14:10 295 查看
以下纯属个人理解之后所写产物,希望大家接受对的,忽略错的。

2018.3.31 补入当前项目使用的EventBus工具类

EventBus大约是2015年开始兴起,但是2016年开始慢慢去普及使用,其内部也采用了注解形式,在开发方面,减少了Android代码的沉淀,使开发者编写的代码更简洁;在功能方面,代替了intent,BroadcaseReceiver的部分功能效果,也实现了跨进程的通信;在优化方面,也在注解内包含了多种运行情况和环境(这一点理解不多)

EventBus使用也比较简单,当然是在你自己静下心潜心看完这篇博客之后,莫像我之前认为很难,其实花20分钟一行一行看完之后,你会发现只需要分分钟搞定,主要记得看思想,用法只是其次

Effect :



使用步骤:

因个人理解与RxJava、RxAndroid有共性处,所以包名附带了Rx系列,同时大家可通过以下博客地址进行学习

http://blog.csdn.net/qq_20451879/article/details/63779434

build 依赖:

compile 'org.greenrobot:eventbus:3.0.0'


自定义一个事件类:

//主要作用于数据存储,I think you konw!
public class MsaEvent{
private String message;
public  MsaEvent(String message){
this.message=message;
}
public String getMessage() {
return message;
}

public void MsaEvent(String message) {
this.message = message;
}
}


发送者:

//这里就是我们要传送过去的数据
EventBus.getDefault().post(new MyFirstEventBus(" to do everything"));


注意:注册、注销与事件处理一般在一个类中

注册事件:

//一般在生命周期的OnCreat中进行注册
EventBus.getDefault().register(this);


注销事件:

//一般在生命周期的onDestroy中进行注销
EventBus.getDefault().unregister(this);


处理事件:

//一般自己事件的处理,我们自定义方法,但是参数要注意,如我们之下的代码中的展示

//这里格外注意的@Subscribe,不理解的话可通过之前附带的RxAndroid链接去进行学习

//Subscribe 事件订阅者

@Subscribe
public void onEventMainThread(MyFirstEventBus messageEvent){
mContent.setText(messageEvent.getStory());
}


Subscribe 可指定线程模型,默认是POSTING

线程模型,借鉴与

EventBus3.0有四种线程模型,分别是:

POSTING (默认) 表示事件处理函数的线程跟发布事件的线程在同一个线程。

MAIN 表示事件处理函数的线程在主线程(UI)线程,因此在这里不能进行耗时操作。

BACKGROUND 表示事件处理函数的线程在后台线程,因此不能进行UI操作。如果发布事件的线程是主线程(UI线程),那么事件处理函数将会开启一个后台线程,如果果发布事件的线程是在后台线程,那么事件处理函数就使用该线程。

ASYNC 表示无论事件发布的线程是哪一个,事件处理函数始终会新建一个子线程运行,同样不能进行UI操作。

Demo展示区

MyFirstEventBus(我们用于放置数据Bean容器):

package com.example.dow.eventbus_rx;

public class MyFirstEventBus {
public String story;

public MyFirstEventBus(String story){
this.story=story;
}

public String getStory() {
return story;
}

public void setStory(String story) {
this.story = story;
}
}


MainActivity :

package com.example.dow.eventbus_rx;

import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;

public class MainActivity extends AppCompatActivity {

private TextView mContent;
private TextView mBtn;
private TextView mIntentBtn;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//第一案例
mBtn = (TextView) findViewById(R.id.tv_btn);
mContent = (TextView) findViewById(R.id.tv_content);

//第二案例
mIntentBtn = (TextView) findViewById(R.id.tv_btn1);

mBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
EventBus.getDefault().post(new MyFirstEventBus("We need happy to do everything"));
}
});

mIntentBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startActivity(new Intent(MainActivity.this,SecoundActivity.class));
}
});

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

/**
*处理事件
* */
@Subscribe
public void onEventMainThread(MyFirstEventBus messageEvent){
mContent.setText(messageEvent.getStory());
}

@Override
protected void onDestroy() {
super.onDestroy();
EventBus.getDefault().unregister(this);
}
}


SecoundActivity :

package com.example.dow.eventbus_rx;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;

ee19
import android.widget.TextView;

import org.greenrobot.eventbus.EventBus;

public class SecoundActivity extends AppCompatActivity {

private TextView mBtn;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_secound);
mBtn = (TextView) findViewById(R.id.secound_content);

mBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
EventBus.getDefault().post(new MyFirstEventBus(" to do everything"));
finish();
}
});

}
}


MainActivity Xml :

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.example.dow.eventbus_rx.MainActivity">

<TextView
android:layout_width="match_parent"
android:padding="5dp"
android:gravity="center"
android:id="@+id/tv_btn"
android:layout_height="wrap_content"
android:text="点击事件" />

<TextView
android:layout_width="match_parent"
android:padding="5dp"
android:gravity="center"
android:id="@+id/tv_content"
android:layout_height="wrap_content"
android:text="EventBus得显示内容" />

<TextView
android:layout_marginTop="20dp"
android:layout_width="match_parent"
android:padding="5dp"
android:gravity="center"
android:id="@+id/tv_btn1"
android:layout_height="wrap_content"
android:text="跳转Secound事件" />

</LinearLayout>


SecoundActivity Xml :

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="match_parent">

<TextView
android:layout_width="match_parent"
android:id="@+id/secound_content"
android:text="让我们愉快的使用一次EventBus"
android:textSize="20sp"
android:gravity="center"
android:layout_height="match_parent" />
</LinearLayout>


项目使用工具:

EventBusUtil

package com.bakheet.garage.utils;

import com.bakheet.garage.common.EventBusBean;

import org.greenrobot.eventbus.EventBus;

/**
* EventBus工具类(提供eventbus的注册/反注册/发送事件/发送粘性事件的方法)
*/

public class EventBusUtil {
public static void register(Object subscriber) {
EventBus.getDefault().register(subscriber);
}

public static void unregister(Object subscriber) {
EventBus.getDefault().unregister(subscriber);
}

public static void postEvent(EventBusBean eventBusBean) {
EventBus.getDefault().post(eventBusBean);
}

//event3.0粘性事件
public static void postStickyEvent(EventBusBean eventBusBean) {
EventBus.getDefault().postSticky(eventBusBean);
}
}


EventBusBean

package com.bakheet.garage.common;

/**
* Created by paul on 2017/8/10.
* EventBus发送的事件实体
*/

public class EventBusBean<T> {
private int code;
private T data;

public EventBusBean(int code) {
this.code = code;
}

public EventBusBean(int code, T data) {
this.code = code;
this.data = data;
}

public int getCode() {
return code;
}

public T getData() {
return data;
}

public void setCode(int code) {
this.code = code;
}

public void setData(T data) {
this.data = data;
}
}


使用方式相同 :

示例

事件发送者

//Constant.EventBusCode.P_REFRESH_CONFIRM_PAGE 为自己抽取的常量内部类
EventBusUtil.postEvent(EventBusBean(Constant.EventBusCode.P_REFRESH_CONFIRM_PAGE));


事件接收者

onCreat 生命周期中

EventBusUtil.register(this);


事件处理

@Subscribe(threadMode = ThreadMode.MAIN)
public void receiveEventBus(EventBusBean eventBusBean) {
if (eventBusBean != null) {
switch (eventBusBean.getCode()) {
case Constant.EventBusCode.REFRESH_CAR_LIST:
Log.e("tag","已经拿到传递的状态或者数据,进行对应的操作");
break;
default:
break;
}
}
}


onDestroy 生命周期中

EventBusUtil.unregister(this);


补充(个人理解,或许为错) :

时隔一年有发现粘性事件的概念,根据个人理解,在使用粘性事件的时候,将立即得到前面粘性事件的事件

这样我认为我在使用粘性事件发送的时候,如果我需要发送三个信息,那么我会间接发出六个事件,指的是发送第二个事件的时候触发之前的第一个事件与本身的事件,同样我们发第三个事件同样会触发第一二个的事件! 所以我认为粘性事件在理解的基础之上,可是适当使用,如不熟悉,并不太建议使用~

使用区别点:

事件发送者

//EventBusStickyMessage为数据体,根据自己随意设定Model即可
EventBus.getDefault().postSticky(new EventBusStickyMessage("我是主页面发送过来的粘性事件"));


事件处理者

//这种写法达到粘性的目的
@Subscribe(sticky = true, threadMode = ThreadMode.MAIN)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息