ANDROID中使用开源框架EVENTBUS3.0实现FRAGMENT之间的通信交互

简介:

1.概述

在之前的博文中简单介绍过如何实现fragment之间的信息交互:《Android中Fragment与Activity之间的交互(两种实现方式)》,今天继续给大家介绍一种可以实现此效果的另外一种方式EventBus。(相比于handler,接口回调,bundle传参,这个简单好用到哭)

EventBus是Android下高效的发布/订阅事件的消息总线。作用是可以代替传统的Intent,Handler,Broadcast或接口函数在Fragment、Activity、Service、线程之间传递数据进行通信,执行方法。做为消息总线,有三个主要元素:

(1)Event:事件

(2)Subscriber:事件订阅者,接受特定的事件

(3)Publisher:事件发布者,用于通知Subscriber有事件发生

结合EventBus以上的三个元素,我们也可以称其为一种观察者设计模式。

EventBus 官网链接http://greenrobot.org/eventbus/

EventBus GitHub链接https://github.com/greenrobot/EventBus

前期相关博文链接:

Android中Fragment与Activity之间的交互(两种实现方式)

Android中Fragment的两种创建方式

2.Demo示例

(1)示例中左侧的按钮,潘侯爷与碧空海触发的事件为EventBus的普通事件发布

(2)左侧粘性事件按钮发布的为粘性事件

3.实现步骤

本次Demo架构:

3.1导依赖包

使用AndroidStudio2.2。仍然采用在build.gradle下中dependencies下直接添加如下代码:

compile 'org.greenrobot:eventbus:3.0.0'

同步后完成依赖添加。

3.2布局文件

(1)layout中主布局文件,activity_main.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="horizontal"
    tools:context="com.mly.panhouye.eventbustest.MainActivity">
    <LinearLayout
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:orientation="vertical"
        android:background="#6f6669">
        <Button
            android:layout_gravity="center_horizontal"
            android:id="@+id/panhouye"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="" />
        <Button
            android:layout_gravity="center_horizontal"
            android:id="@+id/bikonghai"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="" />
        <Button
            android:layout_gravity="center_horizontal"
            android:id="@+id/postSticky"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Д" />
    </LinearLayout>
    <FrameLayout
        android:id="@+id/framelayout"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="2"></FrameLayout>
</LinearLayout>

(2)layout中右侧的fragment布局文件fragment_msg.xml文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">
    <TextView
        android:id="@+id/tv"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="no data"
        android:textSize="50sp"
        android:gravity="center_horizontal"/>
</LinearLayout>

(3)layout中粘性事件的演示界面布局activity_main2.xml文件

<?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:id="@+id/activity_main2"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.mly.panhouye.eventbustest.Main2Activity">
    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:textSize="30sp"
        android:gravity="center_horizontal"
        android:id="@+id/tv"
        android:text="no data"/>
</RelativeLayout>

3.3java实现代码

(1)自定义事件类

本次演示最简单事件的发布,事件仅发布字符串数据,MessageEvent.java文件如下:

package com.mly.panhouye.eventbustest;/**
 * Created by panchengjia on 2017/2/19 0019. */public class MessageEvent {
    String data;    public MessageEvent(String data) {        this.data = data;
    }
}

(2)MsgFragment.java

右侧fragment对应的java类,除了在其中关联其对应的fragment布局外,还需要添加修改fragment中文本的方法,如下:

package com.mly.panhouye.eventbustest;import android.os.Bundle;import android.support.annotation.Nullable;import android.support.v4.app.Fragment;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.TextView;/**
 * Created by panchengjia on 2017/2/20 0020. */public class MsgFragment extends Fragment {
    TextView tv;
    @Nullable
    @Override    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_msg,container,false);
        tv = (TextView) view.findViewById(R.id.tv);        return view;
    }    public void setText(String message){
        tv.setText(message);
    }
}

(3)MainActivity.java

MainActivity.java对应的布局为主布局,右侧的fragment附属于该布局,所以需要在该类中注册EventBus,将当前的Activity注册为事件订阅者,具体代码如下:

package com.mly.panhouye.eventbustest;import android.content.Intent;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.view.View;import android.widget.Button;import org.greenrobot.eventbus.EventBus;import org.greenrobot.eventbus.Subscribe;import org.greenrobot.eventbus.ThreadMode;public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    Button panhouye,bikonghai,postSticky;
    MsgFragment msgFragment;
    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        panhouye= (Button) findViewById(R.id.panhouye);
        bikonghai= (Button) findViewById(R.id.bikonghai);
        postSticky= (Button) findViewById(R.id.postSticky);

        panhouye.setOnClickListener(this);
        bikonghai.setOnClickListener(this);
        postSticky.setOnClickListener(this);        //添加fragment到右侧的帧布局中
        msgFragment = new MsgFragment();
        getSupportFragmentManager().beginTransaction().add(R.id.framelayout,msgFragment).commit();
    }    /*个人建议在onResume注册EventBus
     *在可见可交互状态下注册,尽可能少的占用内存     */
    @Override    protected void onResume() {        super.onResume();
        EventBus.getDefault().register(this);
    }    /*个人建议在onPause注册EventBus(将当前Activity注册为事件订阅者)
     *不影响功能的情况下提早解除注册,尽可能少的占用内存     */
    @Override    protected void onPause() {        super.onPause();
        EventBus.getDefault().unregister(this);
    }    /**
     * 事件发布者(通过按钮点击事件进行事件发布)
     * @param v     */
    @Override    public void onClick(View v) {        switch (v.getId()){            //(1)事件发布中所传参数可以作为右侧fragment文本的修改内容            //(2)事件发布中所传参数也可以用作事件订阅者执行方法的区分通知
            case R.id.panhouye:
                EventBus.getDefault().post(new MessageEvent("潘侯爷"));                break;            case R.id.bikonghai:
                EventBus.getDefault().post(new MessageEvent("碧空海"));                break;            case R.id.postSticky:                //粘性事件发布
                EventBus.getDefault().postSticky(new MessageEvent("粘性事件"));
                startActivity(new Intent(this,Main2Activity.class));                break;
        }
    }    /**
     * 事件订阅者自定义的接收方法
     * @param event     */
    @Subscribe(threadMode = ThreadMode.MAIN)    public void onMessageEvent(MessageEvent event) {//        //(1)将事件发布者发布的数据作为文本修改内容//        msgFragment.setText(event.data);        //(2)将事件发布者发布的数据作为方法执行的区分
        switch(event.data){            case "潘侯爷":
                msgFragment.setText("panhouye");                break;            case "碧空海":
                msgFragment.setText("bikonghai");                break;
        }
    }
}

(4)Main2Activity.java

注意:此布局作为粘性事件发布的订阅者,同样需要注册EventBus

package com.mly.panhouye.eventbustest;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.widget.TextView;import org.greenrobot.eventbus.EventBus;import org.greenrobot.eventbus.Subscribe;import org.greenrobot.eventbus.ThreadMode;public class Main2Activity extends AppCompatActivity {
    TextView tv;
    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);
        tv = (TextView) findViewById(R.id.tv);
    }
    @Override    protected void onResume() {        super.onResume();
        EventBus.getDefault().register(this);
    }
    @Override    protected void onPause() {        super.onPause();
        EventBus.getDefault().unregister(this);
    }
    @Subscribe(threadMode = ThreadMode.MAIN,sticky = true)    public void onMessageEvent(MessageEvent event) {//        //(1)将事件发布者发布的数据作为文本修改内容        tv.setText(event.data);        //(2)将事件发布者发布的数据作为方法执行的区分//        switch(event.data){//            case "粘性事件"://                tv.setText("panhouye");//                break;//        }    }
}

发布的粘性事件在其新订阅者注册后将会自动传递给新订阅者,有时我们也需要移除粘性事件,以免它在传递下去。

MessageEvent stickyEvent = EventBus.getDefault().getStickyEvent(MessageEvent.class);// Better check that an event was actually posted beforeif(stickyEvent != null) {      // "Consume" the sticky event      EventBus.getDefault().removeStickyEvent(stickyEvent);      // Now do something with it}
MessageEvent stickyEvent = EventBus.getDefault().removeStickyEvent(MessageEvent.class);// Better check that an event was actually posted beforeif(stickyEvent != null) {      // Now do something with it}

4.线程模式

EventBus提供了四种线程模式:

(1)postThread:用户将被调用在同一个线程中,这是发布事件(这是默认值)。事件传递意昧着最少的开销,因为它完全避免了线程切换。因此,这是推荐的模式,来处理简单的任务,如果是已知的完成是一个很短的时间,而不需要主线程。事件处理使用此模式必须迅速返回,以避免阻塞发布线程,这可能是主线程。

(2)MainThread:用户将被调用在主线程(UI线程)。如果发布线程是主线程,事件处理程序方法将直接调用。使用此模式的事件处理程序必须快速返回,避免阻塞主线程。

(3)BackgrounThread:将在后台线程中调用订阅者。如果发布线程不是主线程,则事件处理程序方法将被在发布线程中直接调用。如果线程是主线程,eventbus采用单独的一个后台线程,将按顺序调用所有的事件。使用此模式的事件处理程序应尝试快速返回,以避免阻塞后台线程。

(4)Async:事件处理程序方法在一个单独的线程中调用。这总是独立于发布线程和主线程。发布事件从来不会等待使用这种模式的事件处理程序方法。事件处理程序方法使用此模式,如果他们的执行可能需要一段时间,例如用于网络访问。避免触发大量在同一时间运行长时间运行的异步处理程序方法以限制并发线程的数目。eventbus使用一个线程池来有效地重用已完成的异步事件处理程序通知的线程。

本文转自帅气的头头博客51CTO博客,原文链接http://blog.51cto.com/12902932/1927602如需转载请自行联系原作者


sshpp

相关文章
|
7月前
|
消息中间件 网络协议 Java
Android 开发中实现数据传递:广播和Handler
Android 开发中实现数据传递:广播和Handler
69 1
|
7月前
|
Android开发 开发者
Android网络和数据交互: 请解释Android中的AsyncTask的作用。
Android&#39;s AsyncTask simplifies asynchronous tasks for brief background work, bridging UI and worker threads. It involves execute() for starting tasks, doInBackground() for background execution, publishProgress() for progress updates, and onPostExecute() for returning results to the main thread.
40 0
|
Android开发
Android手写占位式插件化框架之Activity通信、Service通信和BroadcastReceiver通信(一)
Android手写占位式插件化框架之Activity通信、Service通信和BroadcastReceiver通信
114 0
|
Android开发
Android手写占位式插件化框架之Activity通信、Service通信和BroadcastReceiver通信(二)
Android手写占位式插件化框架之Activity通信、Service通信和BroadcastReceiver通信
118 0
|
Linux Android开发
[RK3568 Android11] Binder通信整体框架
[RK3568 Android11] Binder通信整体框架
106 0
 [RK3568 Android11] Binder通信整体框架
|
存储 消息中间件 缓存
【Android】开发Android应用时对于Handler消息传递与缓存问题深入运用and理解
【Android】开发Android应用时对于Handler消息传递与缓存问题深入运用and理解
211 0
|
Android开发
Android基础入门:EventBus实现总线数据分发
我们之前学习了Activity-》Activity中的数据传送,是通过intent.putExtra()方法实现的,如果要实现Activity-》Fragment或者Fragment-》Fragment都是不方便的,通过EventBus能很好的解决这个问题
205 0
|
Android开发
【Android 应用开发】Activity生命周期 与 Activity 之间的通信
【Android 应用开发】Activity生命周期 与 Activity 之间的通信
150 0
【Android 应用开发】Activity生命周期 与 Activity 之间的通信
|
Android开发 测试技术 Java
|
Android开发 定位技术 开发工具
Android Lifecycle 对MVP模式进一步”解耦“
传统的MVP模式中,不可避免要在V中的生命周期中要做很多业务操作,导致actitvity等还是臃肿不堪。因此,谷歌在2017年的IO大会上推出了Lifecycle框架,希望借Lifecycle将activity的生命周期事件传递给Presenter,让Presenter承担部分业务,从而降低了Activity的复杂度。
1272 0