Android訊息傳遞之元件間傳遞訊息

總李寫程式碼發表於2016-06-17

前言:

      上篇學習總結了Android通過Handler訊息機制實現了工作執行緒與UI執行緒之間的通訊,今天來學習一下如何實現元件之間的通訊。本文依然是為學習EventBus做鋪墊,有對比才能進步,今天主要介紹在EventBus出現之前的實現方式,通過Intent方式這裡不做介紹。

    訊息傳遞相關文章地址:

需求場景:

      之前做圖片社交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是如何管理事件匯流排的,以及優缺點。

 

相關文章