前言:
上篇學習總結了Android通過Handler消息機制實現了工作線程與UI線程之間的通信,今天來學習一下如何實現組件之間的通信。本文依然是為學習EventBus做鋪墊,有對比才能進步,今天主要介紹在EventBus出現之前的實現方式,通過Intent方式這里不做介紹。
消息傳遞相關文章地址:
- Android消息傳遞之Handler消息機制
- Android消息傳遞之組件間傳遞消息
- Android消息傳遞之EventBus 3.0使用詳解
- Android消息傳遞之基於RxJava實現一個EventBus - RxBus
需求場景:
之前做圖片社交App的時候,需要處理一個點贊數據的同步,比如在作品的詳情頁點贊 需要同時更新列表頁該作品的點贊數量。
方式一:通過動態注冊BroadcastReceiver
1.)內部定義BroadcastReceiver
//同步數據廣播 private BroadcastReceiver dataSynReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { if (intent.getAction().equals("com.whoislcj.broadcastReceiver.dataSynAction")) { int count = intent.getIntExtra("count", 0); //接下來執行同步操作 } } };
2.)在Activity對應的生命周期注冊/解注冊 onCreate/onStart/onResume 注冊 onDestroy/onStop/onPause 解注冊
注冊
//同步數據廣播 private BroadcastReceiver dataSynReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { if (intent.getAction().equals("com.whoislcj.broadcastReceiver.dataSynAction")) { int count = intent.getIntExtra("count", 0); runOnUiThread(new Runnable() { @Override public void run() { //接下來執行同步操作 } }); } } };
解注冊
//解除同步數據廣播 private void unRegisterReceiver() { unregisterReceiver(dataSynReceiver); }
3.)在觸發數據同步的地方發送消息
Intent intent = new Intent(); intent.setAction("com.whoislcj.broadcastReceiver.dataSynAction");//設置Action intent.setPackage(getPackageName());//設置包名使廣播只能被app內接收者接收 intent.putExtra("count", 5);//添加附加信息 sendBroadcast(intent);
4.)分析優缺點
優點:可以設置不同頁面接收消息的優秀級,而且也可以采用發送有序廣播的方式終止將同步消息發給下一級,同時也可以修改消息傳遞給下一級。
缺點:廣播傳遞本身是有安全隱患的,需要設置權限,每一個Activity都要定義、注冊,解注冊廣播無形中加大了工作量和維護成本。
方式二:通過自己管理事件監聽總線
1.)聲明一個數據同步接口
/** * 贊同步接口 */ public interface IDataSynListener { void onDataSyn(int count); }
2.)定義一個單例管理監聽總線
public class DataSynManager { private LinkedList<IDataSynListener> autoListeners = new LinkedList();//監聽集合 private static DataSynManager mInstance;//單例引用 /** * 獲取單例引用 * * @return */ public static DataSynManager getInstance() { if (mInstance == null) { synchronized (DataSynManager.class) { if (mInstance == null) { mInstance = new DataSynManager(); } } } return mInstance; } /** * 添加同步數據監聽 */ public void registerDataSynListener(IDataSynListener autoDataListener) { if (autoListeners == null) { autoListeners = new LinkedList<IDataSynListener>(); } if (!autoListeners.contains(autoDataListener)) { autoListeners.add(autoDataListener); } } /** * 移除同步數據監聽 */ public void unRegisterDataSynListener(IDataSynListener autoDataListener) { if (autoListeners == null) { return; } if (autoListeners.contains(autoDataListener)) { autoListeners.remove(autoDataListener); } } /** * 執行數據同步 * * @param count */ public void doDataSyn(final int count) { if (autoListeners == null) { autoListeners = new LinkedList(); } new Handler().post(new Runnable() { @Override public void run() { for (IDataSynListener dataSynListener : autoListeners) { dataSynListener.onDataSyn(count); } } }); } /** * 清除所有監聽者 */ public void release() { if (autoListeners != null) { autoListeners.clear(); autoListeners = null; } } /** * 贊同步接口 */ public interface IDataSynListener { void onDataSyn(int count); } }
2.)在Activity對應的生命周期添加監聽/移除監聽 onCreate/onStart/onResume 添加監聽 onDestroy/onStop/onPause 移除監聽
添加監聽
DataSynManager.getInstance().registerDataSynListener(dataSynListener);
移除監聽
DataSynManager.getInstance().unRegisterDataSynListener(dataSynListener);
聲明一個監聽
DataSynManager.IDataSynListener dataSynListener=new DataSynManager.IDataSynListener() { @Override public void onDataSyn(int count) { //接下來執行同步操作 } };
3.)在觸發數據同步的地方發送消息
DataSynManager.getInstance().doDataSyn(5);
4.)分析優缺點
優點:相對廣播傳輸安全一點,對於總線數量過大的時候效率可能會比較低。
缺點:不能設置優先級,不能終止傳遞,不能修改消息。
小結:
以上兩種方式是在EventBus出現之前我所使用的實現方式,如果有更好的實現方式,也可以互相學習一下。接下來就是來學習一個EventBus是如何管理事件總線的,以及優缺點。