Android之EventBus

本文介绍EventBus的基本原理及使用方法,演示如何通过观察者模式在不同组件如Service、Activity及Fragment间传递消息。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文主要记录一些零碎的东西

最近面试遇到的问题,不止一次问到 进程间传递消息,我说了使用EventBus可以实现,但是我没有使用过,那个丢人呀,今天过来耍耍Event Bus,这个使用的就是观察者设计模式,看看eventBus怎么使用

代码实现 (是两个Fragment交互, 也可以是Service,Activity,Fragment以及任意类之间交互)
点击左边面板的条目, 可以发送事件,右面板(另一个Fragment)接收到事件,显示界面,信息。


build.gradle 里添加依赖

 // event bus
compile 'de.greenrobot:eventbus:2.4.0'

MainActivity

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

public class MainActivity extends AppCompatActivity {

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

activity_main

<?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:layout_width="match_parent"
    android:layout_height="match_parent"
    android:divider="?android:attr/dividerHorizontal"
    android:orientation="horizontal"
    android:showDividers="middle"
    android:baselineAligned="false"
    tools:context=".MainActivity"
    >
    <fragment
        android:id="@+id/left_fragment"
        android:name="com.slack.cl.eventbus.LeftFragment"
        android:layout_width="0dip"
        android:layout_height="match_parent"
        android:layout_weight="1" />

    <fragment
        android:id="@+id/right_fragment"
        android:name="com.slack.cl.eventbus.RightFragment"
        android:layout_width="0dip"
        android:layout_height="match_parent"
        android:layout_weight="3" />

</LinearLayout>
LeftFragment

import android.os.Bundle;
import android.support.v4.app.ListFragment;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.ListView;

import de.greenrobot.event.EventBus;

/**
 * Created by root on 16-7-15.
 */
public class LeftFragment extends ListFragment {

    String[] strs = new String[]{"主线程消息1", "子线程消息1", "主线程消息2"};

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);


        setListAdapter(new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, strs));
    }

    @Override
    public void onListItemClick(ListView l, View v, int position, long id) {
        switch (position) {
            case 0:
                // 主线程
                System.out.println(
                        "----------------------主线程发的消息1"
                                + " threadName: "+ Thread.currentThread().getName()
                                + " threadId: " + Thread.currentThread().getId());
                EventBus.getDefault().post(new MsgEvent(strs[0]));
                break;
            case 1:
                // 子线程
                new Thread(){
                    public void run() {
                        System.out.println(
                                "----------------------子线程发的消息1"
                                        + " threadName: "+ Thread.currentThread().getName()
                                        + " threadId: " + Thread.currentThread().getId());
                        EventBus.getDefault().post(new MsgEvent(strs[1]));
                    };
                }.start();

                break;
            case 2:
                // 主线程
                System.out.println(
                        "----------------------主线程发的消息2"
                                + " threadName: "+ Thread.currentThread().getName()
                                + " threadId: " + Thread.currentThread().getId());
                EventBus.getDefault().post(new MsgEvent(strs[2]));
                break;
        }
    }

}
RightFragment

import android.graphics.Color;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import de.greenrobot.event.EventBus;

/**
 * Created by root on 16-7-15.
 */
public class RightFragment extends Fragment {
    private TextView textView;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // 界面创建时,订阅事件, 接受消息
        EventBus.getDefault().register(this);
    }
    @Override
    public void onDestroy() {
        super.onDestroy();
        // 界面销毁时,取消订阅
        EventBus.getDefault().unregister(this);
    }
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        textView = new TextView(getContext());
        textView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
        textView.setFocusable(false);
        textView.setTextColor(Color.RED);
        textView.setGravity(Gravity.CENTER);
        return textView;
    }

    /**
     * 与发布者在同一个线程
     * @param msg 事件1
     */
    public void onEvent(MsgEvent msg){
        String content = msg.getMsg()
                + "\n ThreadName: " + Thread.currentThread().getName()
                + "\n ThreadId: " + Thread.currentThread().getId();
        System.out.println("onEvent(MsgEvent1 msg)收到" + content);
        textView.setText("onEvent:"+content);
    }

    /**
     * 执行在主线程。
     * 非常实用,可以在这里将子线程加载到的数据直接设置到界面中。
     * @param msg 事件1
     */
    public void onEventMainThread(MsgEvent msg){
        String content = msg.getMsg()
                + "\n ThreadName: " + Thread.currentThread().getName()
                + "\n ThreadId: " + Thread.currentThread().getId();
        System.out.println("onEventMainThread(MsgEvent1 msg)收到" + content);
        textView.setText("onEventMainThread:"+content);
    }

    /**
     * 执行在子线程,如果发布者是子线程则直接执行,如果发布者不是子线程,则创建一个再执行
     * 此处可能会有线程阻塞问题。
     * @param msg 事件1
     */
    public void onEventBackgroundThread(MsgEvent msg){
        String content = msg.getMsg()
                + "\n ThreadName: " + Thread.currentThread().getName()
                + "\n ThreadId: " + Thread.currentThread().getId();
        System.out.println("onEventBackgroundThread(MsgEvent1 msg)收到" + content);
        textView.setText("onEventBackgroundThread:"+content);
    }

    /**
     * 执行在在一个新的子线程
     * 适用于多个线程任务处理, 内部有线程池管理。
     * @param msg 事件1
     */
    public void onEventAsync(MsgEvent msg){
        String content = msg.getMsg()
                + "\n ThreadName: " + Thread.currentThread().getName()
                + "\n ThreadId: " + Thread.currentThread().getId();
        System.out.println("onEventAsync(MsgEvent1 msg)收到" + content);
        textView.setText("onEventAsync:"+content);
    }

}


主要步骤:
1. 添加订阅者:EventBus.getDefault().register(this); 将所在类作为订阅者,框架会通过反射机制获取所有方法及其参数。
订阅者所在类可以定义以下一个或多个方法用以接收事件:

public void onEvent(MsgEvent msg)

public void onEventMainThread(MsgEvent msg)

public void onEventBackgroundThread(MsgEvent msg)

public void onEventAsync(MsgEvent msg)

2. 发布者发布事件:EventBus.getDefault().post("主线程发的消息1");
一旦执行了此方法, 所有订阅者都会执行第二步定义的方法。
3. 取消订阅:EventBus.getDefault().unregister(this); 当订阅者不再被使用,或者被关闭时,最好进行取消订阅,不再接受事件消息。
4. 注意事项:发布者post方法参数是Object类型,也就是可以发布任何事件。订阅者接受消息时,只要定义的是第二步四个方法任意一个,并且参数和发布者发布的一致,即可被执行。发布者也可以通过第二步接收消息,订阅者也可以作为发布者发消息给自己。








评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值