EventBus原理解析筆記以及案例實(shí)戰(zhàn)(結(jié)合demo)

筆記概述

  • EventBus簡(jiǎn)介

  • EventBus方法介紹

  • EventBus實(shí)際運(yùn)用

EventBus簡(jiǎn)介

  • 開源項(xiàng)目地址:https://github.com/greenrobot/EventBus

  • EventBus主頁:http://greenrobot.org/eventBus/

  • github項(xiàng)目地址中關(guān)于EventBus的簡(jiǎn)介:
    Event bus for Android and Java that simplifies communication between Activities, Fragments, Threads, Services, etc. Less code, better quality.
    即,
    Event 簡(jiǎn)化了活動(dòng)、碎片、進(jìn)程、服務(wù)等之間的通訊方式;
    使APP項(xiàng)目用更少的代碼量實(shí)現(xiàn)更好的質(zhì)量;

  • 關(guān)于EventBus的優(yōu)勢(shì)

  • 簡(jiǎn)化組件間的通訊方式
    • 解耦合事件發(fā)送者和接收者
    • 使活動(dòng)、碎片和后臺(tái)的線程實(shí)現(xiàn)更高的執(zhí)行效率
    • 防止復(fù)雜的有錯(cuò)誤(傾向)的依賴以及生命周期的問題
  • 讓你的代碼簡(jiǎn)潔
  • 運(yùn)行快
  • 庫小
  • EventBus主頁簡(jiǎn)潔:
    EventBus is an open-source library for Android and Java using the publisher/subscriber pattern for loose coupling. EventBus enables central communication to decoupled classes with just a few lines of code – simplifying the code, removing dependencies, and speeding up app development.
    即,
    EventBus是一個(gè)開源庫,
    使用發(fā)布/訂閱機(jī)制來對(duì)代碼進(jìn)行解耦。
    簡(jiǎn)化項(xiàng)目的集中通訊(僅僅通過幾行代碼就可以解耦各個(gè)類),
    移除了一些不必要的依賴,加速移動(dòng)應(yīng)用的開發(fā)。

關(guān)于大項(xiàng)目,如果還是用Java/Android原生的調(diào)用,
兩個(gè)Activity之間的通訊,
還用startActivity()/startActivityForResult()這類通信方式的話,
代碼會(huì)非常的冗余,
例如Activity和Fragment之間的通訊就需要不斷地調(diào)用相關(guān)的函數(shù)
使用EventBus可以解除這些耦合;
否則如果代碼耦合性非常大的話,
會(huì)大大增加后期維護(hù)的難度!



EventBus架構(gòu)

  • Publisher
    調(diào)用post()方法,
    把Event發(fā)送到EventBus;

  • EventBus(類似于快遞中心)
    分發(fā)Publisher發(fā)布的Event
    給對(duì)應(yīng)的Subscriber(訂閱者);

  • Subscriber接收Event;

EventBus概述

  • EventBus是一個(gè)Android端優(yōu)化的
    publish/subscribe消息總線;

  • 簡(jiǎn)化了應(yīng)用程序內(nèi)各組件間、組件與后臺(tái)線程間的通訊;

  • 舉例一個(gè)EventBus可簡(jiǎn)化代碼的場(chǎng)景:
    請(qǐng)求網(wǎng)絡(luò)時(shí)候,等網(wǎng)絡(luò)返回時(shí)通過Handler或Broadcast通知UI;
    兩個(gè)Fragment之間需要通過Listener通訊;
    以上都可以用EventBus來代替;

  • EventBus作為一個(gè)消息總線,有三個(gè)主要的元素:

    • Event:事件
      Event可以是任意對(duì)象,
      用來描述傳遞的數(shù)據(jù)事件類型;
      一般Event是由開發(fā)者按照需求自己定義的,
      里面封裝要傳遞的事件類型和數(shù)據(jù);

    • Subscriber:事件訂閱者,接收待定的事件
      在Event中,使用約定制定事件訂閱者簡(jiǎn)化使用

      在3.0之前,EventBus還沒使用注解的方式,
      消息處理的方法也僅限于:
      onEvent、onEventMainThread、onEventBackgroundThread、onEventSync,
      分別代表四種線程模型;

      在3.0之后,消息處理的方法可以隨便取名,
      但是需要
      添加一個(gè)注解@Subscribe,
      并且要指定線程的模型;

    • Publisher:事件發(fā)布者,用于通知Subscriber有事件發(fā)生
      可以在任意線程、任意位置發(fā)送事件,
      直接調(diào)用EventBuspost(Object)方法即可;

    • 調(diào)用EventBus.getDefault()方法,實(shí)例化EventBus對(duì)象



EventBus線程模型

ThreadMode

ThreadMode指定了會(huì)調(diào)用的函數(shù),
只能有以下四種(因?yàn)槊總€(gè)訂閱事件都是和一個(gè)線程模型相關(guān)的):
PostThread、 BackgroundThread、 MainThread、 Async

PostThread: 在相同的進(jìn)程中做EventBus通信

  • 事件的處理事件的發(fā)送相同的進(jìn)程,
    所以事件的處理時(shí)間不應(yīng)太長(zhǎng),
    不然會(huì)影響事件的發(fā)送線程;
    而這個(gè)線程可能是UI線程;

  • 對(duì)應(yīng)的函數(shù)名是onEvent
    一般在UI線程使用,
    如果堵塞時(shí)間較長(zhǎng)則會(huì)影響其他線程的刷新
    引起界面的卡頓;

    打個(gè)比方說你在UI線程中卡了兩秒等下UI就不動(dòng),不刷新了

相關(guān)地舉一個(gè)案例

  • 這里有兩個(gè)Activity:

    按下Activity1中的Button,
    會(huì)跳轉(zhuǎn)到Activity2;

    按下Activity2中的button,
    會(huì)通過EventBus去通知Activity1;

    Activity1會(huì)通過OnEvent接收,
    如果接收到Activity2發(fā)送過來消息,
    然后觸發(fā)Toast;

接下來新建一個(gè)項(xiàng)目,根據(jù)官方GitHub添加依賴,

implementation 'org.greenrobot:eventbus:3.1.1'

下面是主布局(Activity1):

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/bt_toAc2"
        android:text="跳轉(zhuǎn)到Activity2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</LinearLayout>
  • 然后根據(jù)需求定義Event(類似于Module類),
    這里沒什么特別需求,
    定義一個(gè)簡(jiǎn)單的Event就可以了:
public class MyEvent {

    public String msg;

    public MyEvent() {}

    public MyEvent(String msg) {
        this.msg = msg;
    }
}
  • 接下來,
    要在我們這個(gè)“Activity1”里面注冊(cè) OnEvent ,

    這個(gè)OnEvent 是在跟 發(fā)送事件的線程 同一個(gè)線程里面 接收事件的,

    我們這里雖然是分開兩個(gè)Activity,
    但是Activity本身就都是在主線程里面的;
    所以這里 事件的發(fā)送(在Activity2), 事件的接收(在Activity1)
    都在同一個(gè)線程中;


    即,以上所說的PostThread線程類型中,
    事件的發(fā)送 跟 事件的接收 是在同一個(gè)線程里面的;


    下面注冊(cè)一個(gè)onEvent(),
    如果接收到Activity2發(fā)送過來消息,觸發(fā)Toast;
    /**
     * 注冊(cè)onEvent(),
     * 注意寫上注解!
     */
    @Subscribe
    public void onEvent(MyEvent event) {
        popOutToast("接收到Event:" + event.msg);
    }
    /**
     * 封裝彈出短時(shí)Toast提示
     * @param text 企圖彈出的文本內(nèi)容
     *
     */
    private void popOutToast(String text) {
        Toast.makeText(MainActivity.this,text,Toast.LENGTH_SHORT).show();
    }
  • 使用EventBus的接收方法的活動(dòng),需要在onCreate中注冊(cè)
        EventBus.getDefault().register(this);
  • 反注冊(cè)
    @Override
    protected void onDestroy() {
        super.onDestroy();
        EventBus.getDefault().unregister(this);
    }
  • 整個(gè)Activity1的java代碼:
public class MainActivity extends AppCompatActivity {

    private Button mButton;

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

        //使用EventBus的接收方法的活動(dòng),需要注冊(cè)
        EventBus.getDefault().register(this);

        mButton = findViewById(R.id.bt_toAc2);
        mButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(MainActivity.this, SecondActivity.class);
                startActivity(intent);
            }
        });
    }

    /**
     * 注冊(cè)onEvent(),
     * 注意寫上注解!
     */
    @Subscribe
    public void onEvent(MyEvent event) {
        popOutToast("接收到Event:" + event.msg);
    }

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

    /**
     * 封裝彈出短時(shí)Toast提示
     * @param text 企圖彈出的文本內(nèi)容
     *
     */
    private void popOutToast(String text) {
        Toast.makeText(MainActivity.this,text,Toast.LENGTH_SHORT).show();
    }
}

創(chuàng)建第二個(gè)活動(dòng)SecondActivity,布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/bt_sendMsg"
        android:text="發(fā)送消息"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</LinearLayout>

java:

public class SecondActivity extends AppCompatActivity {

    private Button mButton;

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

        mButton = findViewById(R.id.bt_sendMsg);
        mButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                EventBus.getDefault().post(new MyEvent("洞妖洞妖我是棟二?。?!"));
            }
        });
    }
}

運(yùn)行效果圖:

Activity1:

跳到Activity2,點(diǎn)擊按鈕,彈出Toast:

補(bǔ)充

  • 以上這種場(chǎng)景,
    如果不用EventBus,
    我們可能需要用到Handler + Runnable的方式,
    但是如果有十個(gè)Activity向Activity1發(fā)消息,
    我們就需要寫十個(gè)Handler了,
    這樣子相當(dāng)繁瑣;
    而使用EventBus,
    這里只要稍微用代碼注冊(cè)一下就可以了,
    明顯方便很多,
    一個(gè)方post、一個(gè)onEvent,也很輕松地解耦了;
  • 另外一個(gè)需要注意的地方就是,
    EventBus.getDefault().register(this);系列的注冊(cè)與反注冊(cè)代碼,
    onEvent()系列的接收函數(shù)是緊密綁定的;
    用時(shí)缺一不可,不用時(shí)存一不可,同生同滅;

    也就是說一個(gè)活動(dòng)注冊(cè)onEvent()系列的接收函數(shù)了,
    則必須用EventBus.getDefault().register(this);去注冊(cè),
    不然會(huì)報(bào)錯(cuò);

    而一個(gè)活動(dòng)它沒有寫onEvent()系列的接收函數(shù),
    卻用EventBus.getDefault().register(this);去注冊(cè)了,
    同樣也會(huì)報(bào)錯(cuò)!
  • onEvent()處理時(shí)間比較長(zhǎng),會(huì)導(dǎo)致線程堵塞;
    如以下再onEvent()中掛起線程3秒,模擬3秒處理時(shí)間:
    @Subscribe
    public void onEvent(MyEvent event) {

        //消耗時(shí)間模擬
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        popOutToast("接收到Event:" + event.msg);
    }

接著運(yùn)行項(xiàng)目的話,
會(huì)發(fā)現(xiàn)我們?cè)贏ctivity2中點(diǎn)擊發(fā)送消息的按鈕之后,
要等到3秒鐘,主線程才會(huì)刷新UI(彈出Toast),
這樣子在實(shí)際運(yùn)用中用戶體驗(yàn)很差;

MainThread

  • 其機(jī)制同onEvent()其實(shí)是差不多的,
    發(fā)送接收都是在同一個(gè)線程 主線程 / UI線程中進(jìn)行;

使用:基于PostThread的代碼,
加多一行(threadMode = ThreadMode.MAIN)即可:

    //MainThread
    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onEvent(MyEvent event) {

        //消耗時(shí)間模擬
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        popOutToast("接收到Event:" + event.msg);
    }

BackgroundThread

  • 事件的處理會(huì)在一個(gè)后臺(tái)線程中執(zhí)行,
    對(duì)應(yīng)的函數(shù)名是onEventBackgroundThread;

  • 雖然名字是BackgroundThread,
    事件的處理是在后臺(tái)線程,
    但事件的處理時(shí)間還是不宜太長(zhǎng);

  • 如果發(fā)送事件的線程是在后臺(tái)線程,
    會(huì)直接執(zhí)行事件;

  • 如果當(dāng)前線程是UI線程,
    事件會(huì)被加到一個(gè)隊(duì)列中,
    由一個(gè)線程依次處理這些事件,

    如果某個(gè)事件處理時(shí)間太長(zhǎng),
    會(huì)阻塞隊(duì)列中 排在后面的事件的派發(fā)或處理;

圖解

對(duì)于PostThread和MainThread

一次執(zhí)行
  • 當(dāng)只有一個(gè)線程的時(shí)候,
    post(發(fā)送)和onEvent()是在同一個(gè)線程中去跑的,
    一個(gè)線程里面的話,

    宏觀上來說,其代碼便是一次執(zhí)行的:

對(duì)于BackgroundThread

一一對(duì)應(yīng)
  • 這里有兩個(gè)線程,UI主線程和后臺(tái)線程,
    這個(gè)后臺(tái)線程 專門用來
    處理onEventBackgroundThread方法及其對(duì)應(yīng)的事件的;

    也就是說,
    比如現(xiàn)在主線程里面有一個(gè)post,
    它會(huì)對(duì)應(yīng)執(zhí)行到后臺(tái)的一個(gè)onEventBackgroundThread();
順序執(zhí)行,前者執(zhí)行,后者等待阻塞
  • 一個(gè)前臺(tái)線程的post
    會(huì)對(duì)應(yīng)執(zhí)行到一個(gè)后臺(tái)線程的onEventBackgroundThread()
    來了第二個(gè)post,
    就對(duì)應(yīng)第二個(gè)onEventBackgroundThread()

  • 后臺(tái)線程中的onEventBackgroundThread();
    是按照post順序依次執(zhí)行的;
    如果前面一個(gè)post對(duì)應(yīng)的onEventBackgroundThread();沒有執(zhí)行完,
    這時(shí)候又post了一下,
    那么對(duì)應(yīng)的后面的這個(gè)onEventBackgroundThread()會(huì)等待前面一個(gè)onEventBackgroundThread()執(zhí)行完,它才執(zhí)行;

  • 來個(gè)例子,修改MainActivity代碼:
    //BackgroundThread
    @Subscribe(threadMode = ThreadMode.BACKGROUND)
    public void onEvent(MyEvent event) {

        Log.d(TAG, "onEvent Start!!!!!!!! ");
        //消耗時(shí)間模擬
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        Log.d(TAG, "onEvent End!!!!!!!! ");

//        popOutToast("接收到Event:" + event.msg);
    }
  • 接著運(yùn)行代碼,
    老規(guī)矩,Activity1跳轉(zhuǎn)到Activity2,
    點(diǎn)擊“發(fā)送信息”按鈕,
    連續(xù)點(diǎn)擊兩次(根據(jù)以上SecondActivity中寫的按鈕點(diǎn)擊事件,
    這里可以理解成連續(xù)post兩次,一前一后),
    觀察logcat:

  • 我們可以觀察到兩對(duì)Start和End是順序執(zhí)行的;

  • 執(zhí)行時(shí)候沒有交叉,先第一對(duì),后第二對(duì);
    這里也便驗(yàn)證了以上理論——
    即,
    一一對(duì)應(yīng),一個(gè)post對(duì)應(yīng)一個(gè)event,
    event順序執(zhí)行,
    前post者對(duì)應(yīng)的event執(zhí)行中,
    則后post者對(duì)應(yīng)的event等待阻塞;

  • 其實(shí)把代碼改成MainThread的,
    再運(yùn)行,連續(xù)點(diǎn)擊三次,
    同樣是能體現(xiàn)一一對(duì)應(yīng),順序執(zhí)行,前者執(zhí)行,后者等待阻塞的特性:

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onEvent(MyEvent event) {

        Log.d(TAG, "onEvent Start!!!!!!!! ");
        //消耗時(shí)間模擬
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        Log.d(TAG, "onEvent End!!!!!!!! ");

//        popOutToast("接收到Event:" + event.msg);
    }
  • 但區(qū)別在于,
    Main是執(zhí)行在主線程,
    而Background是執(zhí)行在后臺(tái)線程,
    而且我們前面說過,
    在主線程中執(zhí)行占用資源多、占用時(shí)間長(zhǎng)的任務(wù)是不合適的,
    既不規(guī)范,也影響體驗(yàn);
  • PostThread/MainThread缺點(diǎn):
    執(zhí)行在主線程,
    事件的個(gè)數(shù),事件的耗時(shí),
    都需要做比較嚴(yán)格的限制

  • BackgroundThread缺點(diǎn):
    運(yùn)行在后臺(tái)線程,不占用主線程資源,
    PostThread/MainThread好那么一點(diǎn),
    但是還是沒有解決——
    多個(gè)(>= 2 個(gè))事件時(shí),
    一次處理一個(gè),依次處理,
    前者執(zhí)行,后者等待阻塞
    的問題,
    不適合事件中有耗時(shí)較長(zhǎng)的任務(wù)

Async adj.異步的;

sync n.同時(shí),同步;
  • 事件處理會(huì)在單獨(dú)的線程中執(zhí)行,
    主要用于在后臺(tái)線程中執(zhí)行耗時(shí)操作,
    每個(gè)事件會(huì)開啟一個(gè)線程
    (程序初始化時(shí),已經(jīng)幫我們創(chuàng)建好一個(gè)線程池,
    每次POST一下框架都會(huì)去取一個(gè)線程來執(zhí)行),
    但最好限制線程的數(shù)目
    (線程過多,CPU使用大,設(shè)備耗電快);

    每次POST一下框架都會(huì)去取一個(gè)線程來執(zhí)行,
    線程池中線程之間互相不干擾,可以同時(shí)運(yùn)行

更改代碼:

    //AsyncThread
    @Subscribe(threadMode = ThreadMode.ASYNC)
    public void onEvent(MyEvent event) {

        Log.d(TAG, "onEvent Start!!!!!!!! ");
        //消耗時(shí)間模擬
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        Log.d(TAG, "onEvent End!!!!!!!! ");
    }

執(zhí)行效果:

這次我們可以看到,
事件的處理就沒有——
一次處理一個(gè),依次處理,前者執(zhí)行中,后者等待阻塞的特性了,
因?yàn)楦鱾€(gè)post的事件,
都有各自獨(dú)立的線程去處理,
所以事件的處理運(yùn)行是同時(shí)的、異步的;

小結(jié)

  • PostThread:發(fā)送和接收在同一個(gè)線程;
  • MainThread:發(fā)送和接收同在主線程;
    (應(yīng)用范圍上被PostThread包括)
  • BackgroundThread
  • PostThread/MainThread缺點(diǎn):
    一般執(zhí)行在主線程,
    事件的個(gè)數(shù),事件的耗時(shí),
    都需要做比較嚴(yán)格的限制;

  • BackgroundThread缺點(diǎn):
    運(yùn)行在后臺(tái)線程,不占用主線程資源,
    PostThread/MainThread好那么一點(diǎn),
    但是還是沒有解決——
    多個(gè)(>= 2 個(gè))事件時(shí),
    一次處理一個(gè),依次處理,
    前者執(zhí)行,后者等待阻塞
    的問題,
    不適合事件中有耗時(shí)較長(zhǎng)的任務(wù)

以上三種線程都是不適合跑耗時(shí)操作的;

Async adj.異步的;
核心:異步,同時(shí),高效

  • 事件處理會(huì)在單獨(dú)的線程中執(zhí)行,
    主要用于在后臺(tái)線程中執(zhí)行耗時(shí)操作,
    每個(gè)事件會(huì)開啟一個(gè)線程
    (程序初始化時(shí),已經(jīng)幫我們創(chuàng)建好一個(gè)線程池,
    每次POST一下框架都會(huì)去取一個(gè)線程來執(zhí)行),
    但最好限制線程的數(shù)目
    (線程過多,CPU使用大,設(shè)備耗電快);

    每次POST一下框架都會(huì)去取一個(gè)線程來執(zhí)行,
    線程池中線程之間互相不干擾,可以同時(shí)運(yùn)行

補(bǔ)充:

  • 優(yōu)先級(jí)(priority)就是字面上的意義,
    值越高,優(yōu)先級(jí)越高;

  • sticy即粘性發(fā)送,
    發(fā)送方法EventBus.getDefault().postSticky(new MyEvent());
    注銷粘性event的方法EventBus.getDefault().removeStickyEvent(new MyEvent());
    發(fā)送(postSticky)的時(shí)候,
    項(xiàng)目中有多少Fragment、Activity等載體,
    事件MyEvent就發(fā)送多少份;
    粘性其意義在于,
    無論項(xiàng)目中載體類中
    是否使用EventBus.getDefault().register(this);對(duì)EventBus注冊(cè)過,
    都會(huì)對(duì)其發(fā)送事件,

    若載體注冊(cè)了,則接收處理該粘性事件;
    若載體未注冊(cè),則該粘性事件會(huì)緩存起來,
    一旦載體注冊(cè),馬上接收處理事件

    但由于這種粘性發(fā)送在項(xiàng)目比較大的時(shí)候
    需要占用一定量的緩存資源,
    所以一般使用較少;

  • 另外一個(gè)需要注意的地方就是,
    EventBus.getDefault().register(this);系列的注冊(cè)與反注冊(cè)代碼,
    onEvent()系列的接收函數(shù)是緊密綁定的;
    用時(shí)缺一不可,不用時(shí)存一不可,同生同滅;

    也就是說一個(gè)活動(dòng)注冊(cè)onEvent()系列的接收函數(shù)了,
    則必須用EventBus.getDefault().register(this);去注冊(cè),
    不然會(huì)報(bào)錯(cuò);

    而一個(gè)活動(dòng)它沒有寫onEvent()系列的接收函數(shù),
    卻用EventBus.getDefault().register(this);去注冊(cè)了,
    同樣也會(huì)報(bào)錯(cuò)!

使用技巧

  • 事件只需要傳遞一個(gè)狀態(tài) / 指令,無需傳遞數(shù)據(jù)時(shí),
    event自定義類內(nèi)容可以為空;


    比如一個(gè)只需要傳遞“清空位置信息列表”這個(gè)指令的事件,
    可以這么定義:

    就是定義一個(gè)Event類,但是內(nèi)容為空;

    無需傳遞數(shù)據(jù),
    僅僅event類的類名已經(jīng)具備傳遞的事件、指令意義;

  • 一個(gè)Fragment或者Activity需要接收處理多個(gè)Event時(shí)候,
    通過建立多個(gè)注解方法,并以不同的event 形參
    區(qū)分處理,接收到不同的event時(shí),該做的對(duì)應(yīng)的邏輯
    ;





參考資料:慕課網(wǎng)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 本篇文章主要講解關(guān)于EventBus的使用,下篇文章會(huì)根據(jù)EventBus的使用具體講解其中的原理。雖然現(xiàn)在RxJ...
    Ruheng閱讀 7,038評(píng)論 8 42
  • 先吐槽一下博客園的MarkDown編輯器,推出的時(shí)候還很高興博客園支持MarkDown了,試用了下發(fā)現(xiàn)支持不完善就...
    Ten_Minutes閱讀 653評(píng)論 0 2
  • 我每周會(huì)寫一篇源代碼分析的文章,以后也可能會(huì)有其他主題.如果你喜歡我寫的文章的話,歡迎關(guān)注我的新浪微博@達(dá)達(dá)達(dá)達(dá)s...
    SkyKai閱讀 25,171評(píng)論 23 184
  • EventBus是一個(gè)Android開源庫,其使用發(fā)布/訂閱模式,以提供代碼間的松耦合。EventBus使用中央通...
    壯少Bryant閱讀 719評(píng)論 0 4
  • 文章基于EventBus 3.0講解。首先對(duì)于EventBus的使用上,大多數(shù)人還是比較熟悉的。如果你還每次煩于使...
    Hohohong閱讀 2,430評(píng)論 0 6

友情鏈接更多精彩內(nèi)容