EventBus詳解

EventBus詳解

簡介

github原文java

EventBus...

* simplifies the communication between components
    - decouples event senders and receivers
    - performs well with Activities, Fragments, and background threads
    - avoids complex and error-prone dependencies and life cycle issues
    - makes your code simpler
* is fast
* is tiny (<50k jar)
* is proven in practice by apps with 100,000,000+ installs
* has advanced features like delivery threads, subscriber priorities, etc.

大概意思android

EventBus...
* 簡化組件之間的通訊
    - 發送者和接收者解耦
    - 能夠在Activities, Fragments,background threads(服務、子線程等)之間傳遞數據
    - 避免了依賴和生命週期等容易出錯的問題
    - 讓你的程序看上去更簡潔
* 更快
* 更小(jar包大小小於50k)
* 已經有這麼這麼多應用用過了EventBus。
* 有一些更高級的功能...

看過簡介,應該大概知道EventBus是一個什麼東西了吧git

Github源碼

源碼地址:https://github.com/greenrobot/EventBusgithub

API文檔地址:https://github.com/greenrobot/EventBus/blob/master/HOWTO.mdmarkdown

我的對EventBus的理解

首先要導入jar包,這個就不用多說了,而後要有一個發送者發送一個消息,最後要有一個接收者接收發送過來的消息網絡

所以,在你要給某個接收者發送消息的時候,必定要保證接收者已經註冊了,否者接收者都尚未,誰來接收呢。併發

爲何提到這個呢,由於我剛用的時候,我是想在一個Activity1裏開啓另外一個Activity2,而後用EventBus傳遞過去一個數據,因而我發送了一個消息,而後用Intent開啓另一個Activity2,在Activity2裏註冊了接收者,可是卻沒有收到消息,以後我又先開啓Activity2,等初始化好了之後,再發送消息,Activity2就收到消息了app

因此想一下EventBus的應用場景,若是咱們有一個服務要在後臺一直刷數據,而後在界面上顯示,相似這種場景,咱們就能夠用EventBus來實現異步

普通的頁面跳轉須要傳遞的數據,咱們用Intent就徹底能夠啦。 async

導入jar包

在Gradle文件里加上jar包

P2

消息發送者

很是簡單,就一行代碼

EventBus.getDefault().post(new MessageEvent("Hello everyone!"));

這裏須要傳遞一個數據對象,就是一個普通的Javabean

public class MessageEvent {
    public final String message;

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

消息接收者

註冊接收者

EventBus.getDefault().register(this);

反註冊接收者

EventBus.getDefault().unregister(this);

四個接收方法

  • PostThread: 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 should return quickly to avoid blocking the posting thread, which may be the main thread. Example:
  • 大概意思: 發送者和接收者要在同一個線程,默認是使用這種方式接收,由於他避免了線程的切換,性能開銷更小
// Called in the same thread (default)
public void onEvent(MessageEvent event) {
    log(event.message);
}
  • MainThread: 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. Example:
  • 大概意思: 接收者在主線程(UI線程),由於是在主線程,因此要避免耗時操做阻塞線程。
// Called in Android UI's main thread
public void onEventMainThread(MessageEvent event) {
    textField.setText(event.message);
}
  • BackgroundThread: 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.
  • 大概意思: 接收者是和發送者在同一個後臺線程中接收到消息(它和發送者是在一個線程中,後面有測試),因此若是發送者是在主線程,那麼接收者也是在同一個主線程,因此儘可能避免耗時的操做阻塞線程。
// Called in the background thread
public void onEventBackgroundThread(MessageEvent event){
    saveToDisk(event.message);
}
  • Async: 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.
  • 大概意思: 異步的形式,發送者和接收者不是同一個線程, 若是有一些耗時的操做,例如聯網獲取一些數據等狀況,能夠用異步,可是爲了不同時有太多的並行事件,要儘可能限制併發線程的數量
// Called in a separate thread
public void onEventAsync(MessageEvent event){
    backend.send(event.message);
}

案例

後臺一個Service刷數據,頁面顯示數據

Demo源碼

下載地址(Android Studio工程):http://download.csdn.net/detail/q4878802/9057545

效果圖

P2 P3

Activity

package com.kongqw.kqweventbusdemo;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.TextView;

import com.kongqw.kqweventbusdemo.bean.MessageEvent;
import com.kongqw.kqweventbusdemo.service.KqwService;

import de.greenrobot.event.EventBus;


public class MainActivity extends Activity {

    private TextView mTvShow;

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

        // 顯示信息的TextView
        mTvShow = (TextView) findViewById(R.id.tv_show);
        // 開啓服務 刷數據
        Intent service = new Intent(this, KqwService.class);
        startService(service);
    }

    @Override
    public void onStart() {
        EventBus.getDefault().register(this);
        super.onStart();
    }

    @Override
    public void onStop() {
        EventBus.getDefault().unregister(this);
        super.onStop();
    }

    // Called in Android UI's main thread
    public void onEventMainThread(MessageEvent event) {
        mTvShow.setText("onEventMainThread : \n" + event.message);
    }
}

Service

package com.kongqw.kqweventbusdemo.service;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;

import com.kongqw.kqweventbusdemo.bean.MessageEvent;

import de.greenrobot.event.EventBus;

public class KqwService extends Service {
    public KqwService() {
    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        throw new UnsupportedOperationException("Not yet implemented");
    }

    @Override
    public void onCreate() {
        super.onCreate();

        EventBus.getDefault().post(new MessageEvent("Service 傳遞過來的數據"));
        /* * 模擬網絡刷新數據 */
        new Thread() {
            @Override
            public void run() {

                for (int x = 0; x < Integer.MAX_VALUE; x++) {
                    try {
                        sleep(1000);
                        EventBus.getDefault().post(new MessageEvent("Service 傳遞過來的數據 : " + x));
                        long id = Thread.currentThread().getId();
                        Log.d("KqwService", "Service發送了數據:" + x + "線程ID : " + id);
                    } catch (Exception e) {
                        // TODO
                        Log.d("KqwService", "error :" + e);
                    }
                }
            }
        }.start();
    }
}

XML頁面

<RelativeLayout 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"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/tv_show"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="顯示數據"
        android:textSize="25dp" />

</RelativeLayout>

測試onEvent

  • 測試發送者和接收者在同一個線程
// This method will be called when a MessageEvent is posted
public void onEvent(MessageEvent event) {
    long id = Thread.currentThread().getId();
    Log.d("onEventMainThread", "Thread id = " + id);
    mTvShow.setText("onEvent : " + event.message);
}
  • 結果,線程ID相同
    P7

測試onEventMainThread

  • 測試接收者是在主線程
// Called in Android UI's main thread
public void onEventMainThread(MessageEvent event) {
    long id = Thread.currentThread().getId();
    Log.d("onEventMainThread", "Thread id = " + id);
    mTvShow.setText("onEventMainThread : \n" + event.message);
}
  • 結果,接收者在主線程
    P6

測試onEventBackgroundThread

  • 測試發送者和接收者是在同一個線程
// Called in the background thread
public void onEventBackgroundThread(final MessageEvent event){
    long id = Thread.currentThread().getId();
    Log.d("onEventBackgroundThread", "Thread id = " + id);
    runOnUiThread(new Runnable() {
        @Override
        public void run() {
            mTvShow.setText("onEventBackgroundThread : " + event.message);
        }
    });
}
  • 結果,發送者和接收者是在同一個線程
    P5

測試onEventAsync

  • 測試發送者和接收者不是在同一個線程
// Called in a separate thread
public void onEventAsync(final MessageEvent event) {
    long id = Thread.currentThread().getId();
    Log.d("onEventAsync", "Thread id = " + id);
    runOnUiThread(new Runnable() {
        @Override
        public void run() {
            mTvShow.setText("onEventAsync : " + event.message);
        }
    });
}
  • 結果,發送者和接收者不是在同一個線程
    P4
相關文章
相關標籤/搜索