來不及解釋了缓溅,快上車之EventBus3.0更多實用使用

上一章中介紹了EventBus的基本使用,接下來介紹一下其他的惠昔,如果沒有掌握的可以看上一篇來不及解釋了,快上車之EventBus3.0快速上手

線程控制

在EventBus中有4種線程控制的方式:

1.POSTING:同步模式豹绪,顧名思義只中方式就是接收事件方法的線程和發(fā)送事件方法的線程一致价淌,如果發(fā)送事件是在主線程中,那么接收事件也是在主線程中瞒津。如果發(fā)送事件的是在子線程蝉衣,那么那么接收事件也會發(fā)送事件的子線程執(zhí)行∠矧剑總之會保持一致病毡。

2.MAIN:主線程模式,無論發(fā)送事件是在那個線程發(fā)送屁柏,接收事件一定會在主線程中執(zhí)行啦膜。這樣剛好就解決了只能在主線程中更新UI的問題。

3.BACKGROUND:后臺線程模式淌喻,如果發(fā)送事件的是在主線程中發(fā)送僧家,接收事件就會在新建一個子線程中執(zhí)行。發(fā)送事件是在子線程中執(zhí)行裸删,接收事件就會發(fā)發(fā)送事件的子線程中執(zhí)行八拱。這種模式適合處理耗時任務。

4.ASYNC:新線程模式,無論發(fā)送事件是在何種線程執(zhí)行肌稻,接收事件一定會新建一個子線程去接收清蚀。

線程控制代碼示例:

事件接收代碼,在每一個線程模式里面打印了當前線程的Name灯萍,以下為了編碼方便轧铁,所有代碼均在一個Activity里面完成:

@Subscribe(threadMode = ThreadMode.MAIN)
public void onBusMain(String message){
    Log.v("bus","main"+Thread.currentThread().getName());
}

@Subscribe(threadMode = ThreadMode.POSTING)
public void onBusPosting(String message){
    Log.v("bus","posting"+Thread.currentThread().getName());
}

@Subscribe(threadMode = ThreadMode.BACKGROUND)
public void onBusBackground(String message){
    Log.v("bus","background"+Thread.currentThread().getName());
}

@Subscribe(threadMode = ThreadMode.ASYNC)
public void onBusAsync(String message){
    Log.v("bus","async"+Thread.currentThread().getName());
}

在界面上加入兩個按鈕:

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

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="mainThread"
        android:text="在主線程發(fā)送"
        />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="sonThread"
        android:text="在子線程發(fā)送"
        />

</LinearLayout>

按鈕的點擊事件,一個在主線程發(fā)出事件旦棉,一個在子線程里面發(fā)出事件:

public void mainThread(View view){
    EventBus.getDefault().post("bus");
}

public void sonThread(View view){
    new Thread(new Runnable() {
        @Override
        public void run() {
            EventBus.getDefault().post("bus");
        }
    }).start();
}

點擊主線程按鈕,logcat打印結果:

09-30 15:05:13.296 18777-18777/com.jelly.eventbus V/bus: mainmain
09-30 15:05:13.296 18777-18777/com.jelly.eventbus V/bus: postingmain
09-30 15:05:13.296 18777-26381/com.jelly.eventbus V/bus: backgroundpool-1-thread-2
09-30 15:05:13.296 18777-26380/com.jelly.eventbus V/bus: asyncpool-1-thread-1

點擊子線程按鈕齿风,locat打印結果:

09-30 15:23:11.628 11282-11282/com.jelly.eventbus V/bus: mainmain    
09-30 15:23:11.616 11282-11392/com.jelly.eventbus V/bus: postingThread-220
09-30 15:23:11.616 11282-11392/com.jelly.eventbus V/bus: backgroundThread-220
09-30 15:23:11.616 11282-11394/com.jelly.eventbus V/bus: asyncpool-1-thread-1    

從上面的打印結果來看,可以論述上面的四點結論绑洛。

優(yōu)先級

EventBus可以通過設置每個接收事件方法的優(yōu)先級@Subscribe(priority = 1)開控制接收方法的先后,實例代碼:

@Subscribe(threadMode = ThreadMode.MAIN,priority = 1)
public void onBus1(String msg){
    Log.v("bus",1 + msg);
}

priority的值越大救斑,接收順序就越靠前。如果指定倆個方法的priority的值為1和2真屯,那么priority為2的先接收到脸候,為1的后接收到,還可以在方法內(nèi)通過cancelEventDelivery()截斷事件的傳遞绑蔫。實例代碼:

package com.jelly.eventbus;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;

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

/**
 * Created by Jelly on 2016/9/30.
 */

public class PriorityActivity extends Activity{

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        this.setContentView(R.layout.activity_priority);
        EventBus.getDefault().register(this);
    }

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


    @Subscribe(threadMode = ThreadMode.MAIN,priority = 0)
    public void onBus(String msg){
        Log.v("bus",0 + msg);
    }

    @Subscribe(threadMode = ThreadMode.MAIN,priority = 1)
    public void onBus1(String msg){
        Log.v("bus",1 + msg);
    }

    @Subscribe(threadMode = ThreadMode.POSTING,priority = 2)
    public void onBus2(String msg){
        Log.v("bus",2 + msg);
    }

    @Subscribe(threadMode = ThreadMode.MAIN,priority = 3)
    public void onBus3(String msg){
        Log.v("bus",3 + msg);
    }



    public void click(View view){
        EventBus.getDefault().post("消息");
    }

}

沒有加取消事件的logcat結果:

10-04 15:58:25.505 4614-4614/com.jelly.eventbus V/bus: 3消息
10-04 15:58:25.505 4614-4614/com.jelly.eventbus V/bus: 2消息
10-04 15:58:25.505 4614-4614/com.jelly.eventbus V/bus: 1消息
10-04 15:58:25.505 4614-4614/com.jelly.eventbus V/bus: 0消息

現(xiàn)在加上取消事件傳遞:

@Subscribe(threadMode = ThreadMode.POSTING,priority = 2)
public void onBus2(String msg){
    Log.v("bus",2 + msg);
    EventBus.getDefault().cancelEventDelivery(msg);
}

打印結果:

10-04 15:55:00.685 4614-4614/com.jelly.eventbus V/bus: 3消息
10-04 15:55:00.685 4614-4614/com.jelly.eventbus V/bus: 2消息

在取消事件傳遞的時候有一個注意點运沦,在取消事件傳遞的方法的線程Mode必須是POSTING的,不然會報event handlers may only abort the incoming event的異常配深,可以從cancelEventDelivery的源碼中看到携添,在下面代碼中的最后一個判斷,如果當前事件接收方法不是POSTING,就會拋出這個異常:

    public void cancelEventDelivery(Object event) {
    PostingThreadState postingState = currentPostingThreadState.get();
    if (!postingState.isPosting) {
        throw new EventBusException(
                "This method may only be called from inside event handling methods on the posting thread");
    } else if (event == null) {
        throw new EventBusException("Event may not be null");
    } else if (postingState.event != event) {
        throw new EventBusException("Only the currently handled event may be aborted");
    } else if (postingState.subscription.subscriberMethod.threadMode != ThreadMode.POSTING) {
        throw new EventBusException(" event handlers may only abort the incoming event");
    }

    postingState.canceled = true;
}

黏性事件

EventBus支持粘性事件,粘性事件就是在發(fā)送了事件之后篓叶,再訂閱事件烈掠,而不是在發(fā)送事件之前訂閱,事件接收方法也能收到缸托,通過@Subscribe(sticky = true)去指定左敌,發(fā)送事件必須通過postSticky發(fā)送。示例代碼:

package com.jelly.eventbus;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;

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

/**
 * Created by Jelly on 2016/10/4.
 */

public class StickyActivity extends Activity{

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

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

    @Subscribe(threadMode = ThreadMode.MAIN,sticky = true)
    public void onBus(String msg){
        Log.v("bus",msg);
    }

    public void click(View view){
        EventBus.getDefault().postSticky("消息");
        EventBus.getDefault().register(this);
    }

}

打印結果:

10-04 16:26:43.401 2405-2405/com.jelly.eventbus V/bus: 消息

效率提升

在EventBus3.0中加入了EventBusAnnotationProcessor提升速度:
1.在項目的gradle的dependencies中引入apt俐镐,加入classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8',結果如下:

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:2.2.0'
        classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

2.在app module的build.gradle中應用apt插件,并設置apt生成的索引的包名和類名矫限,加入以下代碼:

apply plugin: 'com.neenbedankt.android-apt'

apt {
    arguments {
        eventBusIndex "com.jelly.eventbus.MyEventBusIndex"
    }
}

apt 'org.greenrobot:eventbus-annotation-processor:3.0.1'

結果如下:

apply plugin: 'com.android.application'
apply plugin: 'com.neenbedankt.android-apt'

android {
    compileSdkVersion 23
    buildToolsVersion "23.0.3"
    defaultConfig {
        applicationId "com.jelly.eventbus"
        minSdkVersion 19
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

apt {
    arguments {
        eventBusIndex "com.jelly.eventbus.MyEventBusIndex"
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    compile 'com.android.support:appcompat-v7:23.4.0'
    testCompile 'junit:junit:4.12'
    compile 'org.greenrobot:eventbus:3.0.0'
    apt 'org.greenrobot:eventbus-annotation-processor:3.0.1'
}

然后重新編譯,記住一定要重新編譯佩抹,不然找不到MyEventBusIndex奇唤,然后在MyApplication里面初始化Index:

EventBus.builder().addIndex(new MyEventBusIndex()).installDefaultEventBus();

現(xiàn)在就可以開始使用了,啦啦啦!

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末匹摇,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子甲葬,更是在濱河造成了極大的恐慌廊勃,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,376評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異坡垫,居然都是意外死亡梭灿,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,126評論 2 385
  • 文/潘曉璐 我一進店門冰悠,熙熙樓的掌柜王于貴愁眉苦臉地迎上來堡妒,“玉大人,你說我怎么就攤上這事溉卓∑こ伲” “怎么了?”我有些...
    開封第一講書人閱讀 156,966評論 0 347
  • 文/不壞的土叔 我叫張陵桑寨,是天一觀的道長伏尼。 經(jīng)常有香客問我,道長尉尾,這世上最難降的妖魔是什么爆阶? 我笑而不...
    開封第一講書人閱讀 56,432評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮沙咏,結果婚禮上辨图,老公的妹妹穿的比我還像新娘。我一直安慰自己肢藐,他們只是感情好故河,可當我...
    茶點故事閱讀 65,519評論 6 385
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著窖壕,像睡著了一般忧勿。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上瞻讽,一...
    開封第一講書人閱讀 49,792評論 1 290
  • 那天鸳吸,我揣著相機與錄音,去河邊找鬼速勇。 笑死晌砾,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的烦磁。 我是一名探鬼主播养匈,決...
    沈念sama閱讀 38,933評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼都伪!你這毒婦竟也來了呕乎?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 37,701評論 0 266
  • 序言:老撾萬榮一對情侶失蹤陨晶,失蹤者是張志新(化名)和其女友劉穎猬仁,沒想到半個月后帝璧,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,143評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡湿刽,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,488評論 2 327
  • 正文 我和宋清朗相戀三年的烁,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片诈闺。...
    茶點故事閱讀 38,626評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡渴庆,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出雅镊,到底是詐尸還是另有隱情襟雷,我是刑警寧澤,帶...
    沈念sama閱讀 34,292評論 4 329
  • 正文 年R本政府宣布漓穿,位于F島的核電站嗤军,受9級特大地震影響,放射性物質發(fā)生泄漏晃危。R本人自食惡果不足惜叙赚,卻給世界環(huán)境...
    茶點故事閱讀 39,896評論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望僚饭。 院中可真熱鬧震叮,春花似錦、人聲如沸鳍鸵。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,742評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽偿乖。三九已至击罪,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間贪薪,已是汗流浹背媳禁。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留画切,地道東北人竣稽。 一個月前我還...
    沈念sama閱讀 46,324評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像霍弹,于是被迫代替她去往敵國和親毫别。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,494評論 2 348

推薦閱讀更多精彩內(nèi)容