EventBus(初步使用)

概述

EventBus是一款针对Android优化的发布/订阅事件总线。主要功能是替代Intent,Handler,BroadCast在Fragment,Activity,Service,
它可以让我们很轻松的实现在Android各个组件之间传递消息,并且代码的可读性更好,耦合度更低,开销小,代码更优雅.

本程序演示得为EventBus的初步使用
  代码结构
EventBus(初步使用)_第1张图片
程序结果
EventBus(初步使用)_第2张图片

使用方法
1.在studio中关联EventBus
     按Ctrl+Alt+Shift+s,弹出此对话框,之后选择"+"号,选择第一个
EventBus(初步使用)_第3张图片
之后搜索EventBus 选择该项,单机ok即可

EventBus(初步使用)_第4张图片
2.关联后开始写主窗体(接收信息)的布局

xml version= "1.0"  encoding= "utf-8" ?>
< RelativeLayout
    xmlns: android = "http://schemas.android.com/apk/res/android"
    xmlns: tools = "http://schemas.android.com/tools"
    android :layout_width= "match_parent"
    android :layout_height= "match_parent"
    tools :context= ".activity.MainActivity">
    < Button
        android :id= "@+id/btn_ok"
        android :layout_width= "wrap_content"
        android :layout_height= "wrap_content"
        android :layout_centerHorizontal= "true"
        android :text= " 由主页面跳转到发送事件的页面 "
        android :textSize= "30sp"/>
    < TextView
        android :id= "@+id/txtShow"
        android :layout_width= "wrap_content"
        android :layout_height= "wrap_content"
        android :text= " 展示 EventBus 发送过来的数据 "
        android :layout_centerHorizontal= "true"
        android :layout_below= "@+id/btn_ok"/>
RelativeLayout>

3.创建一个activity用来发送数据起名为EventBusSendActivity,之后编写该窗体的布局

xml version= "1.0"  encoding= "utf-8" ?>
< RelativeLayout
    xmlns: android = "http://schemas.android.com/apk/res/android"
    xmlns: tools = "http://schemas.android.com/tools"
    android :layout_width= "match_parent"
    android :layout_height= "match_parent"
    tools :context= ".activity.EventBusSendActivity">

    < EditText
        android :id= "@+id/edt_SendContent"
        android :layout_width= "match_parent"
        android :layout_height= "wrap_content"
        android :hint= " 输入要发送的内容 "
        android :lines= "5"/>

    < Button
        android :id= "@+id/btn_Send"
        android :layout_width= "wrap_content"
        android :layout_height= "wrap_content"
        android :layout_below= "@+id/edt_SendContent"
        android :text= " 向主界面发送一个 eventBus 事件 "
        android :textSize= "30sp"/>
RelativeLayout
>

4.创建一个EventBus的事件类
     该类的一个容器,负责存放一些数据,从而让另一个订阅者(接收者),获取消息
代码如下
public class EventBusMessage {
    // 定义发送的消息必须是 String
    public String  Message;
    public  EventBusMessage(String message){
        Message =message;
    }
}
5. EventBusSendActivity发送窗体的代码
package com.dubuwucool.eventbusdemo.activity;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

import com.dubuwucool.eventbusdemo.R;
import com.dubuwucool.eventbusdemo.event.EventBusMessage;

import org.greenrobot.eventbus.EventBus;

public class EventBusSendActivity  extends AppCompatActivity  implements View.OnClickListener {

    private Button  btn_Send;
    private EditText  edt_SendContent;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout. activity_event_bus_send);
        initView();
    }

    private void initView() {
        btn_Send = (Button) findViewById(R.id. btn_Send);
        btn_Send.setOnClickListener( this);
        edt_SendContent = (EditText) findViewById(R.id. edt_SendContent);

    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            // 点击按钮 , 发送数据
            case R.id. btn_Send:
               String content = edt_SendContent.getText().toString();
                // 使用 Event 发送事件 , 需要 post 方法 , 参数也比细数 Event 消息 , 且要和接收数据保持一直
               EventBus.getDefault().post(new EventBusMessage(content));
                //传送消息后 ,关闭此窗体
                finish();
                break;
        }
    }
}


6.主窗体(接收)代码
package com.dubuwucool.eventbusdemo.activity;

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

import com.dubuwucool.eventbusdemo.R;
import com.dubuwucool.eventbusdemo.event.EventBusMessage;

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

public class MainActivity  extends AppCompatActivity  implements View.OnClickListener {
    private Button  btn_ok;
    private TextView  txtShow;

    //EventBus 实际和广播非常相似 , 只不过使用简单 , 代码量少 , 性能更好
    //MainActivity 就是接收消息的类 , 你的事件在哪接收 , 就在哪个类进行 EventBus 的注册和解除操作
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout. activity_main);
        // 初始化控件
        initView();
        // 注册 EventBus, 参数是上下文
        //  有注册 EventBus 就必须有解除注册的操作 ( 一般在 onDestory 方法里执行解除注册 ), 防止 oom
        EventBus. getDefault().register( this);
    }

    private void initView() {
        btn_ok = (Button) findViewById(R.id. btn_ok);
        txtShow = (TextView) findViewById(R.id. txtShow);
        btn_ok.setOnClickListener( this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            // 根据点击事件跳转到发送事件的 activity 里面
            case R.id. btn_ok:
                Intent intent =  new Intent(MainActivity. this, EventBusSendActivity. class);
                startActivity(intent);
                break;
        }
    }
    // 接收消息 , 参数就是我们定义的 EventBus 消息类 , 和发送消息必须是同一个 , EventBus 的注解

    // 在写接收消息的方法时 , 方法名可自动能够自定义 , 参数必须是消息类设置的参数 , 权限必须是 public
    //  方法名是灰色 , 是由于 studio 不识别 EventBus, 但仍可使用
    @Subscribe(threadMode = ThreadMode. MAIN)
    public void receiveMessage(EventBusMessage eventBusMessage){
        txtShow.setText(eventBusMessage. Message);
    }

    // 销毁时解除 EventBus
    @Override
    protected void onDestroy() {
        EventBus. getDefault().unregister( this);
        super.onDestroy();
    }
}

由此便完成了EventBus的简单使用

补充:
在3.0之前,EventBus还没有使用注解方式。消息处理的方法也只能限定于onEvent、onEventMainThread、onEventBackgroundThread和onEventAsync,分别代表四种线程模型。而在3.0之后,消息处理的方法可以随便取名,但是需要添加一个注解@Subscribe,并且要指定线程模型(默认为PostThread),四种线程模型.
注意,事件处理函数的访问权限必须为public,否则会报异常
这里对注解的ThreadMode共有4中方法,做进一步说明这四种方法的区别

这四种方法分别是
ThreadMode.MAIN
ThreadMode.BACKGROUND
ThreadMode.ASYNC
ThreadMode.POSTING

主线程发送消息时
public class MainActivity  extends AppCompatActivity  implements View.OnClickListener {
    private Button  btn_ok;
    private TextView  txtShow;
    private EditText  edt_SendContent;

    //EventBus 实际和广播非常相似 , 只不过使用简单 , 代码量少 , 性能更好
    //MainActivity 就是接收消息的类 , 你的事件在哪接收 , 就在哪个类进行 EventBus 的注册和解除操作
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout. activity_main);
        // 初始化控件
        initView();
        // 注册 EventBus, 参数是上下文
        //  有注册 EventBus 就必须有解除注册的操作 ( 一般在 onDestory 方法里执行解除注册 ), 防止 oom
        // EventBus.getDefault() 获取 EventBus 对象
        EventBus. getDefault().register( this);
    }

    private void initView() {
        btn_ok = (Button) findViewById(R.id. btn_ok);
        txtShow = (TextView) findViewById(R.id. txtShow);
        btn_ok.setOnClickListener( this);
        edt_SendContent = (EditText) findViewById(R.id. edt_SendContent);

    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            // 根据点击事件跳转到发送事件的 activity 里面
            case R.id. btn_ok:
                String content =  edt_SendContent.getText().toString();
                // 使用 Event 发送事件 , 需要 post 方法 , 参数也比细数 Event 消息 , 且要和接收数据保持一直
                EventBus. getDefault().post( new EventBusMessage(content));
                Log. d( "eventBusThread", Thread. currentThread().getName());
        }
    }
    //接收消息,参数就是我们定义的EventBus消息类,和发送消息必须是同一个,EventBus的注解
    // 在写接收消息的方法时 , 方法名可自动能够自定义 , 参数必须是消息类设置的参数 , 权限必须是 public
    //  方法名是灰色 , 是由于 studio 不识别 EventBus, 但仍可使用


    @Subscribe(threadMode = ThreadMode. MAIN)
    public void receiveMessage(EventBusMessage eventBusMessage) {
        txtShow.setText(eventBusMessage. Message);
        Log. d( "eventBusThread""ThreadMode.MAIN" + Thread. currentThread().getName());
    }

    @Subscribe(threadMode = ThreadMode. BACKGROUND)
    public void receiveMessage1(EventBusMessage eventBusMessage) {
        txtShow.setText(eventBusMessage. Message);
        Log. d( "eventBusThread""ThreadMode.MAIN111" + Thread. currentThread().getName());

    }

    // 无论发送方实在子线程还是主线程 , 都会开一个新的子线程去运行
    //
    @Subscribe(threadMode = ThreadMode. ASYNC)
    public void receiveMessage2(EventBusMessage eventBusMessage) {
        txtShow.setText(eventBusMessage. Message);
        Log. d( "eventBusThread""ThreadMode.ASYNC" + Thread. currentThread().getName());
    }
    // 如果发送方实在主线程 就会开一个新的子线程去运行
    // 如果发送方实在子线程 就会在子线程去运行


    // 表示该方法和消息发送在同一个线程
    @Subscribe(threadMode = ThreadMode. POSTING)
    public void receiveMessage3(EventBusMessage eventBusMessage) {
        txtShow.setText(eventBusMessage. Message);
        Log. d( "eventBusThread"" ThreadMode.POSTING" + Thread. currentThread().getName());
    }

    // 销毁时解除 EventBus
    @Override
    protected void onDestroy() {
        EventBus. getDefault().unregister( this);
        super.onDestroy();
    }
}


由图可见:EventBus(初步使用)_第5张图片

posting和MAIN仍会在主线程中运行 ,而BACKGROUND和ASYNC分别会创建一个新的子线程

子线程发送消息时
public class MainActivity  extends AppCompatActivity  implements View.OnClickListener {
    private Button  btn_ok;
    private TextView  txtShow;
    private EditText edt_SendContent;
    //EventBus 实际和广播非常相似 , 只不过使用简单 , 代码量少 , 性能更好
    //MainActivity 就是接收消息的类 , 你的事件在哪接收 , 就在哪个类进行 EventBus 的注册和解除操作
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout. activity_main);
        // 初始化控件
        initView();
        // 注册 EventBus, 参数是上下文
        //  有注册 EventBus 就必须有解除注册的操作 ( 一般在 onDestory 方法里执行解除注册 ), 防止 oom
        // EventBus.getDefault() 获取 EventBus 对象
        EventBus. getDefault().register( this);
    }

    private void initView() {
        btn_ok = (Button) findViewById(R.id. btn_ok);
        txtShow = (TextView) findViewById(R.id. txtShow);
        btn_ok.setOnClickListener( this);
        edt_SendContent = (EditText) findViewById(R.id. edt_SendContent);

    }
    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            // 根据点击事件跳转到发送事件的 activity 里面
            case R.id. btn_ok:
                new Thread( new Runnable() {
                            @Override
                            public void run() {
                               String content =  edt_SendContent.getText().toString();
                                // 使用 Event 发送事件 , 需要 post 方法 , 参数也比细数 Event 消息 , 且要和接收数据保持一直
                               EventBus. getDefault().post( new EventBusMessage(content));
                               Log. d( "eventBusThread",Thread. currentThread().getName());
                           }
                       }).start();
                break;
        }
    }
    // 接收消息 , 参数就是我们定义的 EventBus 消息类 , 和发送消息必须是同一个 , EventBus 的注解

  //在写接收消息的方法时,方法名可自动能够自定义,参数必须是消息类设置的参数,权限必须是public
    //  方法名是灰色 , 是由于 studio 不识别 EventBus, 但仍可使用
    @Subscribe(threadMode = ThreadMode. MAIN)
    public void receiveMessage(EventBusMessage eventBusMessage) {
        txtShow.setText(eventBusMessage. Message);
        Log. d( "eventBusThread", "ThreadMode.MAIN"+Thread. currentThread().getName());
    }
    @Subscribe(threadMode = ThreadMode. BACKGROUND)
    public void receiveMessage1(EventBusMessage eventBusMessage) {
        txtShow.setText(eventBusMessage. Message);
        Log. d( "eventBusThread", "ThreadMode.MAIN111"+Thread. currentThread().getName());

    }
    // 无论发送方实在子线程还是主线程 , 都会开一个新的子线程去运行
    //
    @Subscribe(threadMode = ThreadMode. ASYNC)
    public void receiveMessage2(EventBusMessage eventBusMessage) {
        txtShow.setText(eventBusMessage. Message);
        Log. d( "eventBusThread", "ThreadMode.ASYNC"+Thread. currentThread().getName());
    }
    // 如果发送方实在主线程 就会开一个新的子线程去运行
   //如果发送方实在子线程 就会在子线程去运行
    // 表示该方法和消息发送在同一个线程
    @Subscribe(threadMode = ThreadMode. POSTING)
    public void receiveMessage3(EventBusMessage eventBusMessage) {
        txtShow.setText(eventBusMessage. Message);
        Log. d( "eventBusThread", " ThreadMode.POSTING"+Thread. currentThread().getName());
    }
    // 销毁时解除 EventBus
    @Override
    protected void onDestroy() {
        EventBus. getDefault().unregister( this);
        super.onDestroy();
    }
}
输出的Log如下
EventBus(初步使用)_第6张图片

由此可见
当发送方在子线程运行时
posting和background都会在这个子线程下运行, ASYNC会在一个新的子线程中运行,MAIN在主线程中运行


综上所述,可得出结论:

 

发送方在主线程

发送方在子线程

MAIN

在主线程中运行

在主线程中运行

BACKGROUND

在一个新建的子线程下运行

在该子线程下运行

ASYNC

在一个新建的子线程下运行

在一个新建的子线程下运行

POSTING

在主线程中运行

在该子线程下运行
















你可能感兴趣的:(EventBus)