EventBus3.0开发详解 近万开发者收藏
什么是EventBus?
eventBus是GreenRobot公司出品的一個基于【publish/subscribe】模型的開發庫
1、GreenRobot公司除了出品eventBus還出品了比較有名的greenDao(sqlite數據庫的orm開發框架)
可以看出GreenDao的star數為4581 而EventBus的star數更高 9564 (star數是一個框架/項目影響力的指標)
2、publish/subscribe是一個以發送消息與接收消息模型。以前咱們學習過相似的知識點有
- sendBroadcast與BroadcastReceiver是一個典型
- handler.sendMessage與handleMessage(Message msg)也是一個典型
- 所以該模型主要包含兩個方面 一個是發送消息 一個是接收消息
優點
- 代碼簡潔、層次清晰,大大提高了代碼的可讀性和可維護性。
- 可以通過簡單的代碼把數據傳遞給Activities, Fragments, Threads, Services等等
下載EventBus官方SDK
Github下載地址為:https://github.com/greenrobot/EventBus
EventBus3.0的使用
可以更簡單的在 app/build.gradle中,如下配置即可
然后運行gradle腳本
EventBus的方法非常簡潔只要掌握以下方法基本就可以完成企業開發了
1、注冊與移除
| EventBus.getDefault().register(this) | 注冊 |
| EventBus.getDefault().unregister(this) | 解除 |
以上兩個方法使用上跟廣播接收者的注冊與使用是類似的有注冊必須在使用后移除,以Activity為例:
2、發送消息
發布消息的對象即為【publisher】發布者
EventBus.getDefault().post(new MainMessage(“Hello EventBus”));
Post參數類型為普通javaBean
public class MainMessage {private String msg;public MainMessage(String msg) {this.msg = msg;}public String getMsg() {return msg;} }3、消息的接收處理(建議使用onEventXXX寫法)
接收消息的對象即為【subscriber】 訂閱者
//主線程中執行@Subscribe(threadMode = ThreadMode.MainThread)public void onMainEventBus(MainMessage msg) {Log.d(TAG, "onEventBus() returned: " + Thread.currentThread()); }@Subscribe在案例中會細細地講解 因為是一個大重點
4、案例分析:代替請求碼與響應碼
MainActivity請求一個NextPageActivity要求該NextPageActivity關閉時把數據傳回給MainActivity
startActivityForResult請求代碼略
在zaowu.itheima.com.eventbusdemo.demo1.FistEvent創建消息類(給post作為發送內容)
public class FistEvent {private String msg;public FistEvent(String msg) {this.msg = msg;}public String getMsg() {return msg;}public void setMsg(String msg) {this.msg = msg;} }zaowu.itheima.com.eventbusdemo.demo1.MainActivity
加載布局:layout/activity_main.xml
注冊與移除 訂閱者
public class MainActivity extends AppCompatActivity {private TextView textView;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);textView= (TextView) findViewById(R.id.main_activity_tv);//注冊事件EventBus.getDefault().register(this);}@Overrideprotected void onDestroy() {super.onDestroy();//移除注冊EventBus.getDefault().unregister(this);}public void open(View view) {startActivity(new Intent(this, NextPageActivity.class));}編寫訂閱者接收消息方法
@Subscribe(threadMode = ThreadMode.MAIN) public void onEventMainThread(FistEvent event) {Log.i("itheima", "onEventMainThread:"+event.getMsg()+Thread.currentThread());textView.setText(event.getMsg()); }- @Subscribe設置訂閱者接收處理消息的方法
- 可以給該注解配置線程參數@Subscribe(threadMode = ThreadMode.MAIN)
- ThreadMode用來指定線程
zaowu.itheima.com.eventbusdemo.demo1.NextPageActivity點擊發送消息并關閉
public class NextPageActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_next_page);}public void event1(View view) {//發送消息FistEvent fistMessage = new FistEvent("NextPageActivity-FistEvent");EventBus.getDefault().post(fistMessage);} }運行前后
–>
控件制臺顯示:消息已經由NextPageActivity傳給MainActivity了。顯示main主線程
不過首先注意一點eventBus將消息傳給參數類型一致的方法
eventBus底層post出消息后,會查找作為subscriber訂閱者的參數類型一致的方法然后向這些方法傳遞post出來的消息。
所以當訂閱者有兩個以上參數類型一致的方法時都會接收到消息。
建議開發者創建不同的javaBean類來代表不同的消息類型
ThreadMode原理
| ThreadMode.MAIN | 標注方法運行在主線程,可以更新UI |
| ThreadMode.BACKGROUND | 標注方法運行在子線程,不可以更新UI但可以執行耗時代碼 |
| ThreadMode.POSTING | 標注方法 運行在跟post一樣的線程。如果post在主線程此時相當于MAIN,反之相當于BACKGROUND |
| ThreadMode.ASYNC | 標注方法運行在子程。但是跟BACKGROUND有區別。舉個例子如果ASYNC標注的方法將要運行時有一個BACKGROUND標注的方法正在運行(延時10秒),前者標注的方法不會等待10秒結束再運行,而是另外開一個線程運行 |
以下是EventBus的源代碼分析
案例分析:代替廣播接收者
如果掌握了EventBus就可以不用廣播接收者來發送消息接收消息了,用EventBus更簡潔。
1、創建不同的消息對象
zaowu.itheima.com.eventbusdemo.demo2.MainEvent
zaowu.itheima.com.eventbusdemo.demo2.BackGroundEvent
zaowu.itheima.com.eventbusdemo.demo2.AsyncEvent
zaowu.itheima.com.eventbusdemo.demo2.PostingEvent
2、發送不同的消息
layout/activity_threadmode.xml
zaowu.itheima.com.eventbusdemo.demo2.ThreadModeActivity
3、接收消息
zaowu.itheima.com.eventbusdemo.demo2.ThreadModeActivity
@Subscribe(threadMode = ThreadMode.MAIN) public void onMainEvent(MainEvent event) {Log.i("itheima", "onMainEvent接收事件:"+event.getMsg()+Thread.currentThread()+":"+System.currentTimeMillis()); } @Subscribe(threadMode = ThreadMode.BACKGROUND) public void onBackGroundEvent(BackGroundEvent event) {try {Thread.sleep(10000);} catch (InterruptedException e) {e.printStackTrace();}Log.i("itheima", "onBackGroundEvent接收事件:"+event.getMsg()+Thread.currentThread()+":"+System.currentTimeMillis()); } @Subscribe(threadMode = ThreadMode.ASYNC) public void onAsyncEvent(AsyncEvent event) {Log.i("itheima", "AsyncEvent接收事件:"+event.getMsg()+Thread.currentThread()+":"+System.currentTimeMillis()); } @Subscribe(threadMode = ThreadMode.POSTING) public void onPostingEvent(PostingEvent event) {Log.i("itheima", "onPostingEvent接收事件:"+event.getMsg()+Thread.currentThread()+":"+System.currentTimeMillis()); }運行結果【按點擊順序】
【1】的運行結果為 ThreadMode.MAIN
【2】的運行結果為ThreadMode.BACKGROUND
消息發送到接收到經過了10秒 且運行在子線程
【3】的運行結果為ThreadMode.POSTING 與post在一個線程
【4】測試ThreadMode.ASYNC時按以下順序
運行結果為
說明與ThreadMode.BACKGROUND都是子線程。但是如果后臺有BACKGROUND在運行,ASYCN消息不會等待BACKGOUND完成,而是直接運行。
總結
有了EeventBus代碼會更簡潔。同時它比handler,廣播,內容觀察者的實現都簡潔統一還支持消息接收的線程指定。開發者重點握:ThreadMode變量
原文出處:http://bbs.itheima.com/thread-299831-1-1.html
HermesEventBus
https://github.com/eleme/HermesEventBus
HermesEventBus是一個基于EventBus的、能在進程間發送和接收event的庫,在IPC或者插件開發中非常有用。它底層基于EventBus,并且和EventBus有相同API。
EventBus是Android系統上使用最廣泛的簡化模塊之間通信的庫。但它不支持進程間收發事件。
所以,我開發了HermesEventBus來支持進程間事件收發。
注意:本庫基于EventBus 3.0.0。如果你之前使用的是老版本,那么必須修改你的代碼,否則將無法接收event。但是修改比較簡單。
之前使用“onEventXXX”名字的方法要加上注解,并且在后面附上線程模式:
@Subscribe(threadMode = ThreadMode.MAIN) public void showText(String text) {textView.setText(text); }原理
本庫基于兩個庫開發:Hermes和EventBus。
事件收發是基于EventBus,IPC通信是基于Hermes。Hermes是一個簡單易用的Android IPC庫。
本庫首先選一個進程作為主進程,將其他進程作為子進程。
每次一個event被發送都會經過以下四步:
1、使用Hermes庫將event傳遞給主進程。
2、主進程使用EventBus在主進程內部發送event。
3、主進程使用Hermes庫將event傳遞給所有的子進程。
4、每個子進程使用EventBus在子進程內部發送event。
另外還使用了Concurrent-Utils庫。
用法
本庫能在app內實現多進程event收發,也可以跨app實現event收發。
單一app內的用法
如果你在單一app內進行多進程開發,那么只需要做以下三步:
Step 1
在gradle文件中加入下面的依賴:
dependencies {compile 'xiaofei.library:hermes-eventbus:0.3.0' }如果你使用Maven,那么加入下面的依賴:
<dependency><groupId>xiaofei.library</groupId><artifactId>hermes-eventbus</artifactId><version>0.3.0</version><type>pom</type> </dependency>Step 2
在Application的onCreate中加上以下語句進行初始化:
HermesEventBus.getDefault().init(this);Step 3
每次使用EventBus的時候,用HermesEventBus代替EventBus。
HermesEventBus.getDefault().register(this);HermesEventBus.getDefault().post(new Event());HermesEventBus也能夠在一個進程間傳遞event,所以如果你已經使用了HermesEventBus,那么就不要再使用EventBus了。
Step 4
如果進程不需要再發送和接受event,那么這個進程必須調用:
HermesEventBus.getDefault().destroy();否則你會收到android.os.DeadObjectException和其他一些異常。這些異常會打印一些異常信息但不會導致app崩潰。
多個app間的用法(使用DroidPlugin的時候就是這種情況)
如果你想在多個app間收發event,那么就做如下幾步:
Step 1
在每個app的gradle文件中加入依賴:
dependencies {compile 'xiaofei.library:hermes-eventbus:0.3.0' }如果使用Maven,那么就加入下面的依賴:
<dependency><groupId>xiaofei.library</groupId><artifactId>hermes-eventbus</artifactId><version>0.3.0</version><type>pom</type> </dependency>Step 2
選擇一個app作為主app。你可以選擇任意app作為主app,但最好選擇那個存活時間最長的app。
在使用DroidPlugin的時候,你可以把宿主app作為主app。
在主app的AndroidManifest.xml中加入下面的service:
<service android:name="xiaofei.library.hermes.HermesService$HermesService0"/>你可以加上一些屬性。
Step 3
在app間收發的事件類必須有相同的包名、相同的類名和相同的方法。
務必記住在代碼混淆的時候將這些類keep!!!
Step 4
在主app的application類的onCreate方法中加入:
HermesEventBus.getDefault().init(this);在其他app的Application類的onCreate方法中加入:
HermesEventBus.getDefault().connectApp(this, packageName);“packageName”指的是主app的包名。
Step 5
每次使用EventBus的時候,用HermesEventBus代替EventBus。
HermesEventBus.getDefault().register(this);HermesEventBus.getDefault().post(new Event());HermesEventBus也能夠在一個進程間傳遞event,所以如果你已經使用了HermesEventBus,那么就不要再使用EventBus了。
Step 6
如果進程不需要再發送和接受event,那么這個進程必須調用:
HermesEventBus.getDefault().destroy();否則你會收到android.os.DeadObjectException和其他一些異常。這些異常會打印一些異常信息但不會導致app崩潰。
友情鏈接
Xiaofei’s GitHub: https://github.com/Xiaofei-it
Hermes是一套新穎巧妙易用的Android進程間通信IPC框架。
Shelly是一個面向業務邏輯的編程庫。Shelly庫提供了一種全新的編程模式,將業務對象的變化對各個模塊的影響通過方法鏈表示出來。
AndroidDataStorage是一個簡潔易用并且具有高性能的Android存儲庫。
ComparatorGenerator是一個易用的生成Comparator的工具類。在排序時特別有用。
《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀總結
以上是生活随笔為你收集整理的EventBus3.0开发详解 近万开发者收藏的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: RuntimeException: Pa
- 下一篇: RecyclerView列表控件漂亮时间