Handler
為什么要使用Handler?因為如果將耗時操作放在主線程中會導(dǎo)致ANR,這個時候我們需要把這些耗時的操作,放在一個子線程中,因為子線程涉及到UI更新,但是當(dāng)子線程中有涉及到操作UI的操作時,就會對主線程產(chǎn)生危險,也就是說,更新UI只能在主線程中更新,在子線程中操作是危險的.
這個時候,Handler就出現(xiàn)了來解決這個復(fù)雜的問題,由于Handler運(yùn)行在主線程中(UI線程中),它與子線程可以通過Message對象來傳遞數(shù)據(jù),這個時候,Handler就承擔(dān)著接受子線程傳過來的(子線程用sedMessage()方法傳遞)Message對象,(里面包含數(shù)據(jù)), 把這些消息放入主線程隊列中,配合主線程進(jìn)行更新UI。
對于發(fā)送消息的handler和處理消息的handler需要進(jìn)行傳遞進(jìn)行關(guān)聯(lián),需要在View層例如Activity或者Fragment里需要定義handler并通過handleMessage()方法對傳遞的msg進(jìn)行處理;對于實際發(fā)送消息的VM層或者P層的類需要又View層將handler傳遞過去才能進(jìn)行處理并在handler中處理,這樣就是的View層和VM層存在耦合;
EventBus
EventBus是一個Android端優(yōu)化的publish/subscribe消息總線,簡化了應(yīng)用程序內(nèi)各組件間、組件與后臺線程間的通信。比如請求網(wǎng)絡(luò),等網(wǎng)絡(luò)返回時通過Handler或Broadcast通知UI.
作為一個消息總線,有三個主要的元素:
- Event:事件
- Subscriber:事件訂閱者,接收特定的事件;有onEvent,onEventMainThread,onEventBackgroundThread,onEventAsync這四個方法,分別對應(yīng)不同的處理模式;
- Publisher:事件發(fā)布者,用于通知Subscriber有事件發(fā)生
事件處理有4種模式:
- PostThread:事件的處理在和事件的發(fā)送在相同的進(jìn)程,所以事件處理時間不應(yīng)太長,不然影響事件的發(fā)送線程,而這個線程可能是UI線程。對應(yīng)的函數(shù)名是onEvent。
- MainThread: 事件的處理會在UI線程中執(zhí)行。事件處理時間不能太長,這個不用說的,長了會ANR的,對應(yīng)的函數(shù)名是onEventMainThread。
- BackgroundThread:事件的處理會在一個后臺線程中執(zhí)行,對應(yīng)的函數(shù)名是onEventBackgroundThread,雖然名字是BackgroundThread,事件處理是在后臺線程,但事件處理時間還是不應(yīng)該太長,因為如果發(fā)送事件的線程是后臺線程,會直接執(zhí)行事件,如果當(dāng)前線程是UI線程,事件會被加到一個隊列中,由一個線程依次處理這些事件,如果某個事件處理時間太長,會阻塞后面的事件的派發(fā)或處理。
- Async:事件處理會在單獨的線程中執(zhí)行,主要用于在后臺線程中執(zhí)行耗時操作,每個事件會開啟一個線程(有線程池),但最好限制線程的數(shù)目。適合于長時間的后臺網(wǎng)絡(luò)請求。
使用步驟:
- 定義事件類型:
public class MyEvent {} - 定義事件處理方法:
通過注解的方式實現(xiàn)處理方法定義,具體處理方法名不限定
@Subscribe(threadMode = ThreadMode.MAIN)
public void onEventMainThread - 注冊訂閱者:
一般是在event的處理類中會進(jìn)行eventbus的注冊,例如Activity或者Fragment中進(jìn)行注冊
EventBus.getDefault().register(this) - 發(fā)送事件:
在VM或者P層處理完耗時操作后post event,讓event訂閱者去處理
EventBus.getDefault().post(new MyEvent()) - 取消注冊:
在activity的onDestroy()方法中要取消注冊,如果一直不釋放會導(dǎo)致Bus中的Event隊列內(nèi)存泄露
eventBus.unregister(this);
Handler與EventBus區(qū)別
EventBus是一款針對Android優(yōu)化的發(fā)布/訂閱事件總線。主要功能是替代Intent,Handler,BroadCast在Fragment,Activity,Service,線程之間傳遞消息.優(yōu)點是開銷小,代碼更優(yōu)雅。以及將發(fā)送者和接收者解耦。
通過demo分別寫了Handler和Eventbus對線程消息傳遞的處理,大家可以簡單對比下兩者的區(qū)別,可以發(fā)現(xiàn)EventBus進(jìn)行了完全的解耦。
本文中和demo中使用的是greenrobot的EventBus,github地址如下:
https://github.com/greenrobot/EventBus