1、EventBus
http://greenrobot.org/eventbus/documentation/官方學習文檔
http://greenrobot.org/
EventBus是Android下高效的發佈/訂閱事件總線機制。作用是可以代替傳統的Intent,Handler,Broadcast或接口函數在Fragment,Activity,Service,線程之間傳遞數據,執行方法。特點是代碼簡潔,是一種發佈訂閱設計模式(Publish/Subsribe),或稱作觀察者設計模式。
在實際開發中經常遇到這樣情況
1、activity之間傳遞數據
2、activity與fragment,fragment與fragment之間傳遞數據
3、activity與service之間傳遞數據
4、activiity與broadcast之間傳遞數據
如果按照android api可能要寫很多代碼,有時候還要攜帶context對象,並且很多時間傳遞給activity後要刷新ui。eventbus幫我們做了大量的這樣的工作,代碼簡介,使用訂閱/發佈。
EventBus屬於greenrobot出品,被收錄google Guava庫,Guava庫有很多強大好用的東西
com.google.common.annotations
com.google.common.base
com.google.common.base.internal
com.google.common.cache
com.google.common.collect
com.google.common.eventbus
com.google.common.io
com.google.common.net
com.google.common.primitives
com.google.common.util.concurrent
在當前流行的retrofit(okhttp)網絡庫,不僅支持rxjava,java8,還有就是guava庫,可以學習一下。
另外greenrobot出口另一個greendao數據庫項目也非常好用
在項目中使用eventbus+greendao非常方便
eventbus 使用依賴
compile 'de.greenrobot:eventbus:3.0.0-beta1'
2、EventBus的使用
1、訂閱
訂閱就是需要接收方,好像的們訂閱的報紙,當有了報紙的時候,快遞員就會向我們訂閱方送報。比如在這是MainActivity了訂閱方。
在這裏主要做兩件事
一是訂閱註冊,與取消
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
EventBus.getDefault().register(this);
}
取消訂閱
@Override
protected void onDestroy() {
super.onDestroy();
EventBus.getDefault().unregister(this);
}
二是訂閱事件
就是當訂閱發佈後,我們在這裏做出相應的事件,比如接收數據,更新UI,或者做其他處理。
在這收到發佈的信息後,在主線程中設置textview的值,彈出Toast。
//收到ObjActivity中的數據
@Subscribe(threadMode = ThreadMode.MainThread)
public void myEventBusObj(MyEvent myEvent) {
text.setText(myEvent.getStr());
Toast.makeText(this, myEvent.getStr(), Toast.LENGTH_SHORT).show();
}
2、發佈
public class ObjActivity extends AppCompatActivity {
private Button btn_send;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_obj);
btn_send= (Button) findViewById(R.id.send_obj);
btn_send.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
EventBus.getDefault().post(new MyEvent("222"));
}
});
}
}
通過MyEvent類發送,也可以簡單的只發送一條Message。
public class MyEvent {
private String str;
public MyEvent(String str){
this.str=str;
}
public String getStr() {
return str;
}
}
3、示例
在MainActivity中爲訂閱者,註冊事件,接收事件
package com.example.eventbus;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import de.greenrobot.event.EventBus;
import de.greenrobot.event.Subscribe;
import de.greenrobot.event.ThreadMode;
import event.MyEvent;
import event.PersonEvent;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private Button btn_str;
private Button btn_obj;
private Button btn_person;
private TextView text;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
EventBus.getDefault().register(this);
btn_str = (Button) findViewById(R.id.btn_str);
btn_obj= (Button) findViewById(R.id.btn_obj);
btn_person= (Button) findViewById(R.id.btn_person);
text = (TextView) findViewById(R.id.text);
btn_str.setOnClickListener(this);
btn_obj.setOnClickListener(this);
btn_person.setOnClickListener(this);
}
@Override
public void onClick(View view) {
Intent intent;
switch (view.getId()) {
case R.id.btn_str:
intent = new Intent();
intent.setClass(MainActivity.this, StrActivity.class);
startActivity(intent);
break;
case R.id.btn_obj:
intent = new Intent();
intent.setClass(MainActivity.this, ObjActivity.class);
startActivity(intent);
break;
case R.id.btn_person:
intent = new Intent();
intent.setClass(MainActivity.this, PersonActivity.class);
startActivity(intent);
break;
}
}
//收到StrActivity中的字符串數據
@Subscribe(threadMode = ThreadMode.MainThread)
public void myEventBusStr(String message) {
text.setText(message + "");
Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
}
//收到ObjActivity中的數據
@Subscribe(threadMode = ThreadMode.MainThread)
public void myEventBusObj(MyEvent myEvent) {
text.setText(myEvent.getStr());
Toast.makeText(this, myEvent.getStr(), Toast.LENGTH_SHORT).show();
}
//收到PersonActivity中的的person對象
@Subscribe(threadMode = ThreadMode.MainThread)
public void myEventBusPerson(PersonEvent event) {
text.setText(event.getPerson().getName()+event.getPerson().getAge());
Toast.makeText(this,event.getPerson().getName()+event.getPerson().getAge(), Toast.LENGTH_SHORT).show();
}
@Override
protected void onDestroy() {
super.onDestroy();
EventBus.getDefault().unregister(this);
}
}
第一個ObjActivity,向MainActivity發送MyEvent對象
public class ObjActivity extends AppCompatActivity {
private Button btn_send;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_obj);
btn_send= (Button) findViewById(R.id.send_obj);
btn_send.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
EventBus.getDefault().post(new MyEvent("222"));
}
});
}
}
PersonActivity向MainActivity發送PersonEvent,攜帶Psrson對象。
public class PersonActivity extends AppCompatActivity {
private Button btn_person;
private Person person;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_person);
btn_person= (Button) findViewById(R.id.send_person);
person=new Person();
person.setName("tom");
person.setAge("20");
btn_person.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
EventBus.getDefault().post(new PersonEvent(person));
}
});
}
}
4、訂閱事件線程處理
1、ThreadMode: POSTING
默認爲在發送線程執行,推薦使用,這樣ThreadMode開銷最少,避免線程切換。因此,簡單的任務,已經完成時間短,不
需要要線程的
// Called in the same thread (default)
// ThreadMode is optional here
@Subscribe(threadMode = ThreadMode.POSTING)
public void onMessage(MessageEvent event) {
log(event.message);
}
2、ThreadMode: MAIN主線程
使用些模式,在主線程中,可以刷新UI
// Called in Android UI's main thread
@Subscribe(threadMode = ThreadMode.MAIN)
public void onMessage(MessageEvent event) {
textField.setText(event.message);
}
3、ThreadMode: BACKGROUND後臺線程
// Called in the background thread
@Subscribe(threadMode = ThreadMode.BACKGROUND)
public void onMessage(MessageEvent event){
saveToDisk(event.message);
}
4、ThreadMode: ASYNC異步線程
事件處理在一個特殊的線程中處理,並且是一些耗時的操作,比如網絡請求數據,數據庫查詢等。
// Called in a separate thread
@Subscribe(threadMode = ThreadMode.ASYNC)
public void onMessage(MessageEvent event){
backend.send(event.message);
}
5、EventBus運行速度提升
EventBus提升,EventBus3.0使用註解方式,我們都知道註解是基於反射,反射在運行時期獲取,一般是普通創建java對象的2倍,但爲什麼效率會提升呢。
EventBus使用的是編譯時期註解,註解分兩種,一種是編譯時期,另一個是運行時期。在而EventBus是在編譯時期的註解,這種註解並不會基於反射動態創建,和Butterknife一樣,它生成的代碼於普通創建對象一樣。