Android uses EventBus 3.0, an open source framework, to achieve communication and interaction between Fragment s

Keywords: Android Fragment Java xml

1. overview

In previous blog posts, I briefly introduced how to achieve information exchange between fragment s: ___________<Interaction between Fragment and Activity in Android (two implementations) Today I will continue to introduce EventBus, another way to achieve this effect. (Compared with handler, interface callback, bundle parameter, this is easy to use to cry)

EventBus is an efficient message bus for publish/subscribe events under Android. The function is to replace the traditional Intent,Handler,Broadcast or interface functions to transfer data between Fragment, Activity, Service and thread to communicate and execute methods. As a message bus, there are three main elements:

(1) Event: Events

(2) Subscriber: Event Subscriber, accepting specific events

(3) Publisher: Event publisher, used to notify Subscriber that an event has occurred

Combining the above three elements of EventBus, we can also call it an observer design pattern.

EventBus official website link http://greenrobot.org/eventbus/

EventBus GitHub link https://github.com/greenrobot/EventBus

Previous related blog links:

Interaction between Fragment and Activity in Android (two implementations)

Two Ways to Create Fragment s in Android

2.Demo example

(1) The button on the left side of the example, the event triggered by Lord Pan and Blue Sea, is a common event release for EventBus.
(2) The sticky event button on the left releases sticky events.

3. Implementation steps

Demo Architecture:

3.1 Lead Dependency Package

Use Android Studio 2.2. Still, add the following code directly under dependencies under build.gradle:

compile 'org.greenrobot:eventbus:3.0.0'

Dependency addition is completed after synchronization.

3.2 Layout File

(1) Main layout file, activity_main.xml file in layout

<?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) The fragment layout file fragment_msg.xml file on the right side of the layout

<?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) Viscous Event Demonstration Interface layout activity_main2.xml File in layout

<?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.3 Java implementation code

(1) Customize event classes

The simplest event in this demonstration is publishing. Events only publish string data. MessageEvent.java file is as follows:

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

In addition to associating the corresponding fragment layout with the java class corresponding to the fragment on the right side, we need to add methods to modify the text of the fragment as follows:

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's corresponding layout is the main layout, and the fragment on the right is attached to the layout. Therefore, it is necessary to register EventBus in this class and current Activity as event subscriber. The specific code is as follows:

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);
        //Add to fragment To the frame layout on the right
        msgFragment = new MsgFragment();
        getSupportFragmentManager().beginTransaction().add(R.id.framelayout,msgFragment).commit();
    }
    /*Personal recommendation to register EventBus in onResume
     *Register in visible interactive state with as little memory as possible
     */
    @Override
    protected void onResume() {
        super.onResume();
        EventBus.getDefault().register(this);
    }
    /*Personal suggestion is to register EventBus in onPause (register current Activity as event subscriber)
     *Remove the registration as early as possible without affecting the function and occupy as little memory as possible.
     */
    @Override
    protected void onPause() {
        super.onPause();
        EventBus.getDefault().unregister(this);
    }
    /**
     * Event Publisher (event publishing by clicking event buttons)
     * @param v
     */
    @Override
    public void onClick(View v) {
        switch (v.getId()){
            //(1)The parameters passed in event publishing can be used as the right side fragment Text modification
            //(2)Parameters passed in event publishing can also be used as discriminatory notifications for event subscriber execution methods
            case R.id.panhouye:
                EventBus.getDefault().post(new MessageEvent("Pan Hou Ye"));
                break;
            case R.id.bikonghai:
                EventBus.getDefault().post(new MessageEvent("Blue sky sea"));
                break;
            case R.id.postSticky:
                //Sticky Event Release
                EventBus.getDefault().postSticky(new MessageEvent("Sticky event"));
                startActivity(new Intent(this,Main2Activity.class));
                break;
        }
    }
    /**
     * Event Subscriber Customized Receiving Method
     * @param event
     */
    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onMessageEvent(MessageEvent event) {
//        //(1)Modify data published by event publishers as text
//        msgFragment.setText(event.data);
        //(2)Distinguishing Method Execution from Data Published by Event Publishers
        switch(event.data){
            case "Pan Hou Ye":
                msgFragment.setText("panhouye");
                break;
            case "Blue sky sea":
                msgFragment.setText("bikonghai");
                break;
        }
    }
}

(4)Main2Activity.java

Note: As a subscriber to sticky event publishing, this layout also needs to register 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)Modify data published by event publishers as text
        tv.setText(event.data);
        //(2)Distinguishing Method Execution from Data Published by Event Publishers
//        switch(event.data){
//            case "Sticky event":
//                tv.setText("panhouye");
//                break;
//        }
    }
}

Published sticky events are automatically passed to new subscribers after their new subscribers are registered. Sometimes we need to remove sticky events to prevent them from passing on.

MessageEvent stickyEvent = EventBus.getDefault().getStickyEvent(MessageEvent.class);
// Better check that an event was actually posted before
if(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 before
if(stickyEvent != null) {
      // Now do something with it
}

4. Thread mode

EventBus provides four threading modes:

(1) postThread: The user will be called in the same thread, which is the publish event (which is the default value). Event passing implies minimal overhead because it completely avoids thread switching. Therefore, this is the recommended pattern to handle simple tasks, if it is known to be completed in a very short time, without requiring the main thread. Event processing using this pattern must return quickly to avoid blocking the publishing thread, which may be the main thread.

(2) MainThread: The user will be called in the main thread (UI thread). If the publishing thread is the main thread, the event handler method will be invoked directly. Event handlers using this pattern must return quickly to avoid blocking the main thread.

(3) BackgrounThread: The subscriber will be invoked in the background thread. If the publishing thread is not the main thread, the event handler method will be invoked directly in the publishing thread. If the thread is the main thread, eventbus uses a separate background thread and will call all events sequentially. Event handlers using this pattern should try to return quickly to avoid blocking background threads.

(4) Async: The event handler method is invoked in a separate thread. This is always independent of the publishing thread and the main thread. Publishing events never wait for an event handler method that uses this pattern. Event handler methods use this pattern if their execution may take some time, such as for network access. Avoid triggering a large number of asynchronous handler methods that run for a long time at the same time to limit the number of concurrent threads. Evetbus uses a thread pool to effectively reuse threads notified by completed asynchronous event handlers.

Posted by jaysmyhero on Sun, 31 Mar 2019 13:27:30 -0700