EventBus的使用

EventBus 原来接触过,也使用过,不过感觉效果不太好,就没有仔细看过,今天认真看了下官方文档(源码看完了,没看太懂,好多细节没注意到),自己写个demo测试了下,顺便记录下

GIthub链接

官方使用说明文档

一**.方法介绍**

@Subscribe(threadMode = ThreadMode.MAIN, sticky = true, priority = 0)
注册方法有三个参数:
threadMode :指定消息接收类型,默认为POSTING加粗样式
sticky :是否粘性 默认为false
priority :优先级 默认为0

1.ThreadMode有四种模式,其中下面是个人的理解

/**
* 当threadMode模式为ThreadMode.POSTING 时,发送eventBus的消息不管是否是粘性接收方法都能接收到
* 1.与sticky是否为true无关
* 2.与发送消息是否为粘性无关
* 3.消息的接收顺序与priority值的大小有关,值越大优先级越高
*
* @param event ThreadMode.POSTING:事件处理与发送在同一个线程中,因此线程不能被阻塞
*


* ThreadMode.MAIN:事件处理在UI线程中,因此不能进行耗时操作
*


* ThreadMode.MAIN_ORDERED 事件处理始终排队进行处理
*


* ThreadMode.BACKGROUND 在Android上,将在后台线程中调用订阅者。如果发布线程不是主线程,则将在发布线程中直接调用订阅者方法*。
* 如果发布线程是主线程,则EventBus使用单个后台线程,
* 该线程将按顺序传递其所有事件。使用此模式的订阅者应尝试
快速返回以避免阻止后台线程。如果不在Android上,则始终使用后台线程
*


* ThreadMode.ASYNC 始终调用单独的线程,处理耗时操作,网络操作,如果任务过多会启用线程池进行线程的复用
*/
2.sticky 设置是否为粘性,
粘性:会保存在内存中
非粘性:不会保存在内存中
3.priority 优先级
int类型 ,数值越大,接收消息的优先级越大,

4.EventBus.getDefault().register(this); 注册eventBus事件,可以在activity,fragment,service中使用

5.EventBus.getDefault().unregister(this); 取消注册eventBus事件,可以在activity,fragment,service中使用

6.EventBus.getDefault().isRegistered(this) 判断是否已经注册

7.EventBus.getDefault().postSticky(); 发送粘性消息

8.EventBus.getDefault().post();; 发送非粘性消息

9.EventBus.getDefault().removeStickyEvent() 移除粘性消息

10.EventBus.getDefault().removeAllStickyEvents(); 移除所有的粘性消息

11.EventBus.getDefault().cancelEventDelivery(); //阻止其它注册的事件接收该消息 ,其中threadmode 必须为POSTING才能使用,否则会报错;

  1. EventBus.getDefault().getStickyEvent() 获取最新的粘性事件

二,使用

在app.build中引入

dependencies {
 
    implementation 'org.greenrobot:eventbus:3.1.1'
}

1.activity中分两种情况

   public class MainActivity extends AppCompatActivity {

    private static final String TAG = "MainActivity";
    private TextView textSend;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textSend = findViewById(R.id.textSend);
        textSend.setOnClickListener(v -> {
            startActivity(new Intent(MainActivity.this, ReceiverActivity.class));
        });
    }


    @Subscribe(threadMode = ThreadMode.MAIN, sticky = true, priority = 0)
    public void defaultMessageText(MessageEvent event) {
        try {
            if (event == null) {
                Log.d(TAG, "defaultMessageText: ------event:null");
                return;
            }
            JSONObject jsonObject = new JSONObject(event.getMessage());
            Log.d(TAG, "defaultMessageText: -------event:" + event + "\n" + "name:" + jsonObject.optString("name"));
        } catch (JSONException e) {
            e.printStackTrace();
            Log.d(TAG, "defaultMessageText: -------event:" + event.getMessage());
        }
    }


    @Override
    protected void onStart() {
        super.onStart();
        if (!EventBus.getDefault().isRegistered(this)) {
            EventBus.getDefault().register(this);
        }
    }

    @Override
    protected void onStop() {
        super.onStop();
        if (EventBus.getDefault().isRegistered(this)) {
            EventBus.getDefault().unregister(this);
        }
    }
}



ReceiverActivity代码

public class ReceiverActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_receiver);
        Button sendText = findViewById(R.id.sendMes);
        sendText.setOnClickListener(v -> {
            sendText();
        });
    }


    void sendText() {
        String mesJson = "{\"name\":\"张三\",\"age\":\"24\",\"address\":{\"province\":\"江苏\",\"city\":\"苏州\",\"street\":\"元和\"}}";
        MessageEvent messageEvent = MessageEvent.ceratMesEvent(mesJson);
        EventBus.getDefault().postSticky(messageEvent);
        finish();
    }
}

MessageEvent代码

public class MessageEvent {

    public String Message;
    //json;string
    public String type;


    public static MessageEvent ceratMesEvent(String message) {
        return new MessageEvent(message);
    }


    public MessageEvent(String message) {
        Message = message;
    }


    public String getMessage() {
        return Message;
    }

    public void setMessage(String message) {
        Message = message;
    }
}

分别在activity1的onstart()和onstop()注册和取消注册,当点击按钮跳转到activity2,在activity2中点击按钮发送消息,并且结束activity2,这时,使用非粘性发送消息,activity1是接收不到消息的,必须使用粘性发送才能接收到消息

如果activity1中的注册和取消注册分别在oncreat或者是ondestory中,在activity2中使用非粘性就能接收到消息了,代码如下

MainActivity

public class MainActivity extends AppCompatActivity {

    private static final String TAG = "MainActivity";
    private TextView textSend;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        if (!EventBus.getDefault().isRegistered(this)) {
            EventBus.getDefault().register(this);
        }
        textSend = findViewById(R.id.textSend);
        textSend.setOnClickListener(v -> {
            startActivity(new Intent(MainActivity.this, ReceiverActivity.class));
        });
    }




    @Subscribe(threadMode = ThreadMode.MAIN, sticky = false, priority = 0)
    public void defaultMessageText(MessageEvent event) {
        try {
            if (event == null) {
                Log.d(TAG, "defaultMessageText: ------event:null");
                return;
            }
            JSONObject jsonObject = new JSONObject(event.getMessage());
            Log.d(TAG, "defaultMessageText: -------event:" + event + "\n" + "name:" + jsonObject.optString("name"));
        } catch (JSONException e) {
            e.printStackTrace();
            Log.d(TAG, "defaultMessageText: -------event:" + event.getMessage());
        }
    }


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

ReceiverActivity

public class ReceiverActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_receiver);
        Button sendText = findViewById(R.id.sendMes);
        sendText.setOnClickListener(v -> {
            sendText();
        });
    }


    void sendText() {
        String mesJson = "{\"name\":\"张三\",\"age\":\"24\",\"address\":{\"province\":\"江苏\",\"city\":\"苏州\",\"street\":\"元和\"}}";
        MessageEvent messageEvent = MessageEvent.ceratMesEvent(mesJson);
        EventBus.getDefault().post(messageEvent);
        finish();
    }
}

2.service,activity之间的消息传递

MyService 代码中启动一个定时的线程,定时发送数据,然后在activity中接收

package com.ytlz.myeventbus;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;

import com.ytlz.myeventbus.evbusObject.MessageEvent;

import org.greenrobot.eventbus.EventBus;

import java.util.Date;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class MyService extends Service {

    ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();

    public MyService() {

    }

    Runnable runnable = new Runnable() {
        @Override
        public void run() {
            Date date = new Date();
            EventBus.getDefault().post(new MessageEvent("我是Service发来的消息:时间是"+date.getHours()+"h"+date.getMinutes()+"m"+date.getSeconds()+"s"));
        }
    };

    @Override
    public void onCreate() {
        super.onCreate();
        sendMesTiming();
    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        throw new UnsupportedOperationException("Not yet implemented");
    }


    void sendMesTiming(){
        service.scheduleWithFixedDelay(runnable, 200, 3000, TimeUnit.MILLISECONDS);
    }

}

MainActivity代码和上面一致,在使用service与activity发送消息时,一定要注意activity的生命周期,当activity不可见时,接收到service信息时,是不能更新ui的

3.fragment,activity之间的消息传递

fragment代码就一个按钮,点击发送消息给activity

package com.ytlz.myeventbus.fragment;

import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;

import com.ytlz.myeventbus.MainActivity;
import com.ytlz.myeventbus.R;
import com.ytlz.myeventbus.evbusObject.MessageEvent;

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

/**
 * Created by wyb on 2019-09-17.
 */

public class SendMesFragment extends Fragment {
    private static final String TAG = "SendMesFragment";
    Button button;

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = (View) inflater.inflate(R.layout.fragment_sendmes, container, false);
        initViews(view);
        return view;
    }


    void initViews(View view) {
        button = view.findViewById(R.id.fSend1);
        button.setOnClickListener(v -> {
            EventBus.getDefault().post(MessageEvent.ceratMesEvent("我是fragment"));

        });
    }
}

FragmentTestActivity 代码 其中 SendMesFragment 是依附在FragmentTestActivity 中的

public class FragmentTestActivity extends AppCompatActivity {
    private static final String TAG = "FragmentTestActivity";
    TextView receiveText;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        EventBus.getDefault().register(this);
        setContentView(R.layout.activity_fragment_test);
        receiveText = findViewById(R.id.receiveText);
    }


    @Subscribe(threadMode = ThreadMode.MAIN)
    public void activityMesReceiver(MessageEvent event) {
        if (receiveText == null) {
            Log.d(TAG, "activityMesReceiver: receiveText can not be null");
            return;
        }
        if (event==null || TextUtils.isEmpty(event.getMessage())){
            Log.d(TAG, "activityMesReceiver: event is null");
            return;
        }
        receiveText.setText(event.getMessage());
    }


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

SendMesFragment 与其它非宿主activity进行信息传递

public class SendMesFragment extends Fragment {
    private static final String TAG = "SendMesFragment";
    Button button;

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = (View) inflater.inflate(R.layout.fragment_sendmes, container, false);
        initViews(view);
        return view;
    }


    void initViews(View view) {
        button = view.findViewById(R.id.fSend1);
        button.setOnClickListener(v -> {
            //这里要使用粘性发送消息,否则接收不到
            EventBus.getDefault().postSticky(MessageEvent.ceratMesEvent("我是fragment"));
            //跳转到mainActivity,并且传递消息给Mainactivity
            startActivity(new Intent(getActivity(), MainActivity.class));
        });
    }


    @Subscribe(threadMode = ThreadMode.POSTING, sticky = false, priority = 0)
    public void defaultMessageText(MessageEvent event) {
        Log.d(TAG, "defaultMessageText: -------event:" + event.getMessage());
        EventBus.getDefault().cancelEventDelivery(event);
        button.setText(event.getMessage());
    }
}

MainActivity 代码

public class MainActivity extends AppCompatActivity {

    private static final String TAG = "MainActivity";
    private TextView textSend;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //startService(new Intent(this, MyService.class));
        textSend = findViewById(R.id.textSend);
        textSend.setOnClickListener(v -> {
            //startActivity(new Intent(MainActivity.this, ReceiverActivity.class));
            EventBus.getDefault().post(MessageEvent.ceratMesEvent("我是Mainactivity返回的消息"));
            finish();
        });
    }

总结:eventBus的灵活使用可以使我们的代码简洁不少,各种界面之间的通信,传值变得非常方便,我们可以把eventBus进行二次封装,其中吧eventMes进行封装成公共类,这样我们只需要根据eventMes其中一个参数的类型来进行消息的处理就行了

你可能感兴趣的:(Android,学习笔记)