国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統(tǒng) > Android > 正文

Android EventBus 3.0.0 使用總結(jié)(必看篇)

2019-10-23 18:28:51
字體:
供稿:網(wǎng)友

前言

EventBus框架

EventBus是一個通用的叫法,例如Google出品的Guava,Guava是一個龐大的庫,EventBus只是它附帶的一個小功能,因此實際項目中使用并不多。用的最多的是greenrobot/EventBus,這個庫的優(yōu)點是接口簡潔,集成方便,但是限定了方法名,不支持注解。另一個庫square/otto修改自 Guava ,用的人也不少。所以今天我們研究的目標是greenrobot的EventBus.

EventBus 簡介

1、EventBus3.0.0 是最新的版本。
2、EventBus 是Android 發(fā)布/訂閱事件總線,可簡化 Activities, Fragments, Threads, Services 等組件間的消息傳遞。
3、可替代 Intent, Handler, BroadCast ,接口等傳統(tǒng)方案,更快,代碼更小,50K 左右的 jar 包,代碼更優(yōu)雅,徹底解耦。

github地址:https://github.com/greenrobot/EventBus

EventBus原理圖

eventbus,android,3.0

如何添加依賴

在module的build.gredle 文件中的dependencies標簽中添加

compile 'org.greenrobot:eventbus:3.0.0'

例如

apply plugin: 'com.android.application'android {  compileSdkVersion 24  buildToolsVersion "24.0.3"  defaultConfig {    applicationId "com.eventbus.app"    minSdkVersion 14    targetSdkVersion 24    versionCode 1    versionName "1.0"  }  buildTypes {    release {      minifyEnabled false      proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'    }  }}dependencies {  compile fileTree(dir: 'libs', include: ['*.jar'])  compile 'com.android.support:appcompat-v7:24.2.1'  compile 'org.greenrobot:eventbus:3.0.0'}

如何使用

注冊事件

EventBus.getDefault().register( this );

取消注冊

EventBus.getDefault().unregister( this );

發(fā)送數(shù)據(jù)

EventBus.getDefault().post( "我發(fā)射了");

簡單小例子:使用EventBus傳遞簡單字符串

package com.eventbus.app;import android.os.Bundle;import android.support.v7.app.AppCompatActivity;import android.view.View;import android.widget.Toast;import org.greenrobot.eventbus.EventBus;import org.greenrobot.eventbus.Subscribe;import org.greenrobot.eventbus.ThreadMode;public class MainActivity extends AppCompatActivity {  @Override  protected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_main);    //注冊    EventBus.getDefault().register( this );    findViewById( R.id.button).setOnClickListener(new View.OnClickListener() {      @Override      public void onClick(View v) {        EventBus.getDefault().post( "我發(fā)射了");      }    });  }  /**   * 自定義一個方法 hello() ,用來接收事件。   * 方法名字可以隨便寫   * @return   */  @Subscribe(threadMode = ThreadMode.MAIN)  public void hello ( String event){    /* Do something */    Toast.makeText( this , event , Toast.LENGTH_SHORT).show();  };  @Override  protected void onDestroy() {    super.onDestroy();    //取消注冊 , 防止Activity內(nèi)存泄漏    EventBus.getDefault().unregister( this );  }}

線程模型

在接收事件消息的方法中,可以通過注解的方式設(shè)置線程模型,EventBus內(nèi)置了4中線程模型,分別是ThreadMode.POSTING 、ThreadMode.MAIN、ThreadMode.BACKGROUND、ThreadMode.ASYNC

比如:

@Subscribe(threadMode = ThreadMode.POSTING)  public void onMessageEventPostThread(String event) {    Log.e( "event PostThread", "消息: " + event + " thread: " + Thread.currentThread().getName() );  }  @Subscribe(threadMode = ThreadMode.MAIN)  public void onMessageEventMainThread(String event) {    Log.e( "event MainThread", "消息: " + event + " thread: " + Thread.currentThread().getName());  }  @Subscribe(threadMode = ThreadMode.BACKGROUND)  public void onMessageEventBackgroundThread(String event) {    Log.e( "event BackgroundThread", "消息: " + event + " thread: " + Thread.currentThread().getName());  }  @Subscribe(threadMode = ThreadMode.ASYNC)  public void onMessageEventAsync(String event) {    Log.e( "event Async", "消息: " + event + " thread: " + Thread.currentThread().getName());  }

PostThread:如果使用事件處理函數(shù)指定了線程模型為PostThread,那么該事件在哪個線程發(fā)布出來的,事件處理函數(shù)就會在這個線程中運行,也就是說發(fā)布事件和接收事件在同一個線程。在線程模型為PostThread的事件處理函數(shù)中盡量避免執(zhí)行耗時操作,因為它會阻塞事件的傳遞,甚至有可能會引起ANR。

MainThread:如果使用事件處理函數(shù)指定了線程模型為MainThread,那么不論事件是在哪個線程中發(fā)布出來的,該事件處理函數(shù)都會在UI線程中執(zhí)行。該方法可以用來更新UI,但是不能處理耗時操作。

BackgroundThread:如果使用事件處理函數(shù)指定了線程模型為BackgroundThread,那么如果事件是在UI線程中發(fā)布出來的,那么該事件處理函數(shù)就會在新的線程中運行,如果事件本來就是子線程中發(fā)布出來的,那么該事件處理函數(shù)直接在發(fā)布事件的線程中執(zhí)行。在此事件處理函數(shù)中禁止進行UI更新操作。

Async:如果使用事件處理函數(shù)指定了線程模型為Async,那么無論事件在哪個線程發(fā)布,該事件處理函數(shù)都會在新建的子線程中執(zhí)行。同樣,此事件處理函數(shù)中禁止進行UI更新操作。

小例子1: 在子線程發(fā)送數(shù)據(jù)

package com.eventbus.app;import android.os.Bundle;import android.support.v7.app.AppCompatActivity;import android.util.Log;import android.view.View;import org.greenrobot.eventbus.EventBus;import org.greenrobot.eventbus.Subscribe;import org.greenrobot.eventbus.ThreadMode;public class MainActivity extends AppCompatActivity {  @Override  protected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_main);    //注冊    EventBus.getDefault().register( this );    findViewById( R.id.button).setOnClickListener(new View.OnClickListener() {      @Override      public void onClick(View v) {        new Thread(new Runnable() {          @Override          public void run() {            Log.d( "event 發(fā)射數(shù)據(jù)線程 : " , Thread.currentThread().getName() ) ;            EventBus.getDefault().post( "我發(fā)射了");          }        }).start() ;      }    });  }  @Subscribe(threadMode = ThreadMode.POSTING)  public void onMessageEventPostThread(String event) {    Log.e( "event PostThread", "消息: " + event + " thread: " + Thread.currentThread().getName() );  }  @Subscribe(threadMode = ThreadMode.MAIN)  public void onMessageEventMainThread(String event) {    Log.e( "event MainThread", "消息: " + event + " thread: " + Thread.currentThread().getName());  }  @Subscribe(threadMode = ThreadMode.BACKGROUND)  public void onMessageEventBackgroundThread(String event) {    Log.e( "event BackgroundThread", "消息: " + event + " thread: " + Thread.currentThread().getName());  }  @Subscribe(threadMode = ThreadMode.ASYNC)  public void onMessageEventAsync(String event) {    Log.e( "event Async", "消息: " + event + " thread: " + Thread.currentThread().getName());  }  @Override  protected void onDestroy() {    super.onDestroy();    //取消注冊 , 防止Activity內(nèi)存泄漏    EventBus.getDefault().unregister( this );  }}

運行結(jié)果:

D/event 發(fā)射數(shù)據(jù)線程 :: Thread-109
E/event BackgroundThread: 消息: 我發(fā)射了 thread: Thread-109
E/event PostThread: 消息: 我發(fā)射了 thread: Thread-109
E/event Async: 消息: 我發(fā)射了 thread: pool-1-thread-2
E/event MainThread: 消息: 我發(fā)射了 thread: main

小例子2: 在主線程發(fā)送數(shù)據(jù)

package com.eventbus.app;import android.os.Bundle;import android.support.v7.app.AppCompatActivity;import android.util.Log;import android.view.View;import org.greenrobot.eventbus.EventBus;import org.greenrobot.eventbus.Subscribe;import org.greenrobot.eventbus.ThreadMode;public class MainActivity extends AppCompatActivity {  @Override  protected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_main);    //注冊    EventBus.getDefault().register( this );    findViewById( R.id.button).setOnClickListener(new View.OnClickListener() {      @Override      public void onClick(View v) {        Log.d( "event 發(fā)射數(shù)據(jù)線程 : " , Thread.currentThread().getName() ) ;        EventBus.getDefault().post( "我發(fā)射了");      }    });  }  @Subscribe(threadMode = ThreadMode.POSTING)  public void onMessageEventPostThread(String event) {    Log.e( "event PostThread", "消息: " + event + " thread: " + Thread.currentThread().getName() );  }  @Subscribe(threadMode = ThreadMode.MAIN)  public void onMessageEventMainThread(String event) {    Log.e( "event MainThread", "消息: " + event + " thread: " + Thread.currentThread().getName());  }  @Subscribe(threadMode = ThreadMode.BACKGROUND)  public void onMessageEventBackgroundThread(String event) {    Log.e( "event BackgroundThread", "消息: " + event + " thread: " + Thread.currentThread().getName());  }  @Subscribe(threadMode = ThreadMode.ASYNC)  public void onMessageEventAsync(String event) {    Log.e( "event Async", "消息: " + event + " thread: " + Thread.currentThread().getName());  }  @Override  protected void onDestroy() {    super.onDestroy();    //取消注冊 , 防止Activity內(nèi)存泄漏    EventBus.getDefault().unregister( this );  }}

運行結(jié)果:

D/event 發(fā)射數(shù)據(jù)線程 :: main
E/event MainThread: 消息: 我發(fā)射了 thread: main
E/event PostThread: 消息: 我發(fā)射了 thread: main
E/event Async: 消息: 我發(fā)射了 thread: pool-1-thread-3
E/event BackgroundThread: 消息: 我發(fā)射了 thread: pool-1-thread-4

黏性事件

除了上面講的普通事件外,EventBus還支持發(fā)送黏性事件。何為黏性事件呢?簡單講,就是在發(fā)送事件之后再訂閱該事件也能收到該事件,跟黏性廣播類似。具體用法如下:

注冊

EventBus.getDefault().register( this );

事件接收

@Subscribe(threadMode = ThreadMode.MAIN , sticky = true )public void onMessageEventMainThread(String event) {Log.e( "event MainThread", "消息: " + event + " thread: " + > Thread.currentThread().getName());}

 

取消注冊

EventBus.getDefault().unregister( this ) ;

發(fā)送事件

EventBus.getDefault().postSticky( "我發(fā)射了");

小例子:在MainActivity發(fā)送事件,在Activity2里注冊并且接收事件

MainActivity源碼

package com.eventbus.app;import android.content.Intent;import android.os.Bundle;import android.support.v7.app.AppCompatActivity;import android.util.Log;import android.view.View;import org.greenrobot.eventbus.EventBus;public class MainActivity extends AppCompatActivity {  @Override  protected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_main);    findViewById( R.id.button).setOnClickListener(new View.OnClickListener() {      @Override      public void onClick(View v) {        Log.d( "event 發(fā)射數(shù)據(jù)線程 : " , Thread.currentThread().getName() ) ;        EventBus.getDefault().postSticky( "我發(fā)射了");        startActivity( new Intent( MainActivity.this , Activity2.class ));      }    });  }}

Activity2源碼

package com.eventbus.app;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.util.Log;import org.greenrobot.eventbus.EventBus;import org.greenrobot.eventbus.Subscribe;import org.greenrobot.eventbus.ThreadMode;public class Activity2 extends AppCompatActivity {  @Override  protected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_2);    //注冊    EventBus.getDefault().register( this );  }  @Subscribe(threadMode = ThreadMode.MAIN , sticky = true )  public void onMessageEventMainThread(String event) {    Log.e( "event MainThread", "消息: " + event + " thread: " + Thread.currentThread().getName());  }  @Override  protected void onDestroy() {    super.onDestroy();    //取消注冊 , 防止Activity內(nèi)存泄漏    EventBus.getDefault().unregister( this ) ;  }}

這就是粘性事件,能夠收到訂閱之前發(fā)送的消息。但是它只能收到最新的一次消息,比如說在未訂閱之前已經(jīng)發(fā)送了多條黏性消息了,然后再訂閱只能收到最近的一條消息。

EventBus源碼分析

Subscribe 接口源碼

@Documented@Retention(RetentionPolicy.RUNTIME)@Target({ElementType.METHOD})public @interface Subscribe {  ThreadMode threadMode() default ThreadMode.POSTING;  /**   * If true, delivers the most recent sticky event (posted with   * {@link EventBus#postSticky(Object)}) to this subscriber (if event available).   */  boolean sticky() default false;  /** Subscriber priority to influence the order of event delivery.   * Within the same delivery thread ({@link ThreadMode}), higher priority subscribers will receive events before   * others with a lower priority. The default priority is 0. Note: the priority does *NOT* affect the order of   * delivery among subscribers with different {@link ThreadMode}s! */  int priority() default 0;}

可以看出默認的線程模型是ThreadMode.POSTING ;默認黏性事件為false,也就是默認不開啟黏性事件;默認的優(yōu)選級為0 。

EventBus 類部分源碼

static volatile EventBus defaultInstance;   /** Convenience singleton for apps using a process-wide EventBus instance. */  public static EventBus getDefault() {    if (defaultInstance == null) {      synchronized (EventBus.class) {        if (defaultInstance == null) {          defaultInstance = new EventBus();        }      }    }    return defaultInstance;  }

getDefault() 是一個單例模式 , 只有一個實例對象。

ThreadMode 類源碼

public enum ThreadMode {  /**   * Subscriber will be called in the same thread, which is posting the event. This is the default. Event delivery   * implies the least overhead because it avoids thread switching completely. Thus this is the recommended mode for   * simple tasks that are known to complete is a very short time without requiring the main thread. Event handlers   * using this mode must return quickly to avoid blocking the posting thread, which may be the main thread.   */     POSTING,  /**   * Subscriber will be called in Android's main thread (sometimes referred to as UI thread). If the posting thread is   * the main thread, event handler methods will be called directly. Event handlers using this mode must return   * quickly to avoid blocking the main thread.   */     MAIN,  /**   * Subscriber will be called in a background thread. If posting thread is not the main thread, event handler methods   * will be called directly in the posting thread. If the posting thread is the main thread, EventBus uses a single   * background thread, that will deliver all its events sequentially. Event handlers using this mode should try to   * return quickly to avoid blocking the background thread.   */     BACKGROUND,  /**   * Event handler methods are called in a separate thread. This is always independent from the posting thread and the   * main thread. Posting events never wait for event handler methods using this mode. Event handler methods should   * use this mode if their execution might take some time, e.g. for network access. Avoid triggering a large number   * of long running asynchronous handler methods at the same time to limit the number of concurrent threads. EventBus   * uses a thread pool to efficiently reuse threads from completed asynchronous event handler notifications.   */  ASYNC}

這個類是枚舉類,定義了線程模型中的幾種類型。

以上這篇Android EventBus 3.0.0 使用總結(jié)(必看篇)就是小編分享給大家的全部內(nèi)容了,希望能給大家一個參考,也希望大家多多支持VEVB武林網(wǎng)。


注:相關(guān)教程知識閱讀請移步到Android開發(fā)頻道。
發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 麻江县| 灌云县| 绥阳县| 丽江市| 岑溪市| 台北县| 梧州市| 宜州市| 句容市| 渭源县| 东明县| 布拖县| 昭苏县| 嘉善县| 保靖县| 上饶市| 名山县| 新安县| 炎陵县| 海林市| 金秀| 阆中市| 清河县| 怀化市| 延安市| 长寿区| 德兴市| 屯留县| 罗定市| 义乌市| 龙海市| 泸定县| 黔东| 凤城市| 政和县| 灵宝市| 通道| 桓台县| 江安县| 扶余县| 临高县|