前言:
上篇學習總結了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是如何管理事件匯流排的,以及優缺點。