EventBus的使用(组件间通信)

EventBus(GitHub地址):https://github.com/greenrobot/EventBus

EventBus 是一款针对 Android 优化的发布/订阅事件总线。
EventBus 能极大简化两个组件之间的通信问题,且效率极高。
EventBus 3.0版本后,开发者能够自定义订阅方法的名字,而没必要规定以“onEventXX”开头的方法了,这样也自由化了很多,而且支持了粘性事件的分发等。

主要功能:替代Intent,Handler,BroadCast 在 Activity与Activity、Activity与Fragment,Service,线程之间传递消息或数据。

优点:开销小、代码更优雅、发送者和接收者解耦。

原理

这里写图片描述

实现步骤 —>

第一步,添加依赖,目前版本是3.1.1,根据最新版本更改

compile 'org.greenrobot:eventbus:3.1.1'

第二步,自定义消息事件,构造中的参数可以根据需求定义数据类型

public class MessageEvent {

    private String message;

    public MessageEvent(String message){
        this.message = message;
    }

    public String getMessage(){
        return message;
    }
}

第三步,注册、注销 EventBus,自定义订阅方法

//在 onCreate 方法中注册 EventBus
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    //需要接收数据的组件,注册 EventBus,成为订阅者
    EventBus.getDefault().register(this);
}

//在 onDestroy方法中注销 EventBus
@Override
public void onDestroy() {
    super.onDestroy();
    //需要接收数据的组件,注销 EventBus
    EventBus.getDefault().unregister(this);
}

/*
EventBus 3.0之后,订阅方法的方法名支持自定义,无需硬性规定以 onEventXX 开头定
义的方法名,但要用 public 修饰该方法,需要使用 @Subscribe 注解,表示在调用
register后该订阅方法才有效,当接收到事件的时候,会调用该方法。
只有那些同时满足public访问权限、非static方法、非abstract方法、有且只有一个参数
和使用了@Subscribe注解的方法才被当做是合法的订阅者方法。

EventBus 中的 threadMode ---->
ThreadMode.Main:如果当前线程就是主线程,那么直接调用订阅者方法,在主线程执行。反之,先进入队列,后面将在主线程的Handler中调用订阅者方法。
ThreadMode.MAIN_ORDERED:直接进入队列,后面将在主线程的Handler中调用订阅者方法。
ThreadMode.Post:该方法的执行和事件发送者在同一个线程中,适用于对是否在
主线程执行无要求的情况,但post线程为主线程,则不能有耗时操作。
ThreadMode.Background:如果发送事件的线程不是UI线程,则运行在该线程中。如果发
送事件的是UI线程,则它运行在由EventBus维护的一个单独的线程中。多个事件会同步地被
这个单独的后台线程所处理。适用于轻微耗时的操作,比如读写数据库。
ThreadMode.Async:运行在单独的工作线程中,不论发送事件的线程是否为主线程。
跟BackgroundThread不一样,该模式的所有线程是独立的,因此适用于长耗时操作,例如网络访问。
*/
//需要接受数据的组件,自定义订阅方法
@Subscribe(threadMode = ThreadMode.MAIN)
public void onEvent(MessageEvent messageEvent){
    Log.d(TAG, "receive message");
    textView.setText(messageEvent.getMessage());
}

第四步,发送消息

public void onClick(View view){
   String text = "组件间通信成功:数据同步完成";
   EventBus.getDefault().post(new MessageEvent(text));
}

第五步,混淆

官方混淆配置: http://greenrobot.org/eventbus/documentation/proguard/

//防止被混淆
-keepattributes *Annotation*
-keepclassmembers class * {
    @org.greenrobot.eventbus.Subscribe <methods>;
}
-keep enum org.greenrobot.eventbus.ThreadMode { *; }

# Only required if you use AsyncExecutor
-keepclassmembers class * extends org.greenrobot.eventbus.util.ThrowableFailureEvent {
    <init>(java.lang.Throwable);
}

几个扩展方法

粘性事件(未完待续)

完整代码

//MessageEvent.java
public class MessageEvent {

    private String message;

    public MessageEvent(String message){
        this.message = message;
    }

    public String getMessage(){
        return message;
    }
}
//activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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="com.example.test.MainActivity">

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="onClick"
        android:text="打开SecondActivity" />

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:text="MainActivity" />
</FrameLayout>
//activity_second.xml

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

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="onClick"
        android:text="打开ThirdActivity" />

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:text="SecondActivity" />
</FrameLayout>
//activity_third.xml

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

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="onClick"
        android:text="组件通信" />

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:text="ThirdActivity" />
</FrameLayout>
//MainActivity.java
public class MainActivity extends Activity {

    private static final String TAG = "MainActivity.this";
    private TextView textView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //需要接受数据的地方,注册EventBus
        EventBus.getDefault().register(this);
        textView = (TextView) findViewById(R.id.textView);
    }

    public void onClick(View view) {
        startActivity(new Intent(this, SecondActivity.class));
    }

    //订阅方法,当接收到事件的时候,会调用该方法
    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onEvent(MessageEvent messageEvent){
        Log.d(TAG, "receive message");
        textView.setText(messageEvent.getMessage());
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        EventBus.getDefault().unregister(this);
    }
}
//SecondActivity.java
public class SecondActivity extends AppCompatActivity {

    private static final String TAG = "SecondActivity.this";
    private TextView textView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);
        //需要接受数据的地方,注册EventBus
        EventBus.getDefault().register(this);
        textView = (TextView) findViewById(R.id.textView);
    }

    public void onClick(View view){
        startActivity(new Intent(this, ThirdActivity.class));
    }

    //订阅方法,当接收到事件的时候,会调用该方法
    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onEvent(MessageEvent messageEvent){
        Log.d(TAG, "receive message");
        textView.setText(messageEvent.getMessage());
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        EventBus.getDefault().unregister(this);
    }
}
//ThirdActivity.java
public class ThirdActivity extends Activity {

    private TextView textView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_third);
        textView = (TextView) findViewById(R.id.textView);
    }

    public void onClick(View view){
        String text = "组件间通信成功:数据同步完成";
        EventBus.getDefault().post(new MessageEvent(text));
        textView.setText(text);
    }
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Vue2中,兄弟组件通信可以通过以下几种方式实现: 1. 使用事件总线(eventBus):创建一个Vue实例作为事件中心,兄弟组件通过该事件中心进行通信。需要在事件中心实例上定义事件和对应的处理函数,在一个组件中触发事件,另一个组件监听并处理该事件。 2. 使用Vuex:Vuex是Vue的官方状态管理库,可以在兄弟组件共享数据。在Vuex中,将需要共享的数据存储在state中,通过mutations进行修改,兄弟组件可以通过获取和修改state中的数据来进行通信。 3. 使用provide/inject:provide和inject是Vue2提供的一种高级选项,可以在祖先组件中通过provide提供数据,然后在后代组件中通过inject注入并使用这些数据。 这些方法都可以实现兄弟组件通信,具体选择哪种方法取决于你的应用场景和需求。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [vue实现的组件兄弟通信功能示例](https://download.csdn.net/download/weixin_38528939/12949066)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [Vue中组件8中通信方式](https://blog.csdn.net/u012260238/article/details/100056012)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值