Androidローカル放送LocalBroadcastManager

23875 ワード

LocalBroadcastManagerはandroidだと信じていますsupport.v 4の1つのクラスで、ローカルブロードキャストは、App内部でしか伝播しません.よく知られているブロードキャストです.BrocastReceiverはグローバルブロードキャストで、プロセスをまたいで通信できますが、LocalBroadcastManagerは、ローカルメッセージとデータ転送の手段としてだけです.もちろん、EventBusのようなメッセージイベントライブラリを再利用する人も少なくありませんが、サードパーティのライブラリは好きではありません.EventBusも小さいですが、これまでBrocastReceiverを使っていましたが、勝手にして、後で接触する項目が多くなって、多くのことを考えなければなりません.
LocalBroadcastManagerを使用するメリット:
  • 1.App内部にしか転送できず、他のAppに受信されず、データセキュリティ
  • を確保する.
  • 2.他のAppブロードキャストは受信できません.干渉なし
  • 3.BrocastReceiverよりも効率的な
  • ただし、LocalBroadcastManagerは静的に登録できず、動的に登録するしかないという特性も2つ目に反映されており、他のAppのブロードキャストを受信する必要はありません.では、どのように使用するかを見てみましょう.
    private LocalBroadcastManager lm;
    private TestReceiver testReceiver;
    
    private void initReceiver() {
        //    
        lm = LocalBroadcastManager.getInstance(this);
        IntentFilter intentFilter = new IntentFilter("com.android.Test");
        testReceiver = new TestReceiver();
        //  
        lm.registerReceiver(testReceiver,intentFilter);
    }
    
    private class TestReceiver extends BroadcastReceiver{
    
        @Override
        public void onReceive(Context context, Intent intent) {
            String action  = intent.getAction();
            Toast.makeText(MainActivity.this, "action:" + action, Toast.LENGTH_SHORT).show();
        }
    }
    
    @Override
    protected void onDestroy() {
        super.onDestroy();
        //  
        lm.unregisterReceiver(testReceiver);
    }
    
    

    使用方法はBrocastReceiverとあまり差がありませんが、LocalBroadcastManagerを使ったことがあることに注意してください.getInstanceインスタンスを取得した後、登録、バインド解除、送信にはこのインスタンスが必要です.
    ソースコード
    LocalBroadcastManagerのソースコードがどのように機能しているかを見てみましょう.実際には、彼のソースコードもあまりありません.彼の取得は単一の例で実現されています.
    @NonNull
    public static LocalBroadcastManager getInstance(@NonNull Context context) {
        Object var1 = mLock;
        synchronized(mLock) {
            if (mInstance == null) {
                mInstance = new LocalBroadcastManager(context.getApplicationContext());
            }
    
            return mInstance;
        }
    }
    
    private LocalBroadcastManager(Context context) {
        this.mAppContext = context;
        this.mHandler = new Handler(context.getMainLooper()) {
            public void handleMessage(Message msg) {
                switch(msg.what) {
                case 1:
                    LocalBroadcastManager.this.executePendingBroadcasts();
                    break;
                default:
                    super.handleMessage(msg);
                }
    
            }
        };
    }
    
    

    単一の例の後、構造関数にHandlerが初期化されました.このHandlerは待っています.次に、彼の登録を見てみましょう.
    public void registerReceiver(@NonNull BroadcastReceiver receiver, @NonNull IntentFilter filter) {
        HashMap var3 = this.mReceivers;
        synchronized(this.mReceivers) {
    		//       
            LocalBroadcastManager.ReceiverRecord entry = new LocalBroadcastManager.ReceiverRecord(filter, receiver);
            ArrayList<LocalBroadcastManager.ReceiverRecord> filters = (ArrayList)this.mReceivers.get(receiver);
            if (filters == null) {
                filters = new ArrayList(1);
          		//     
                this.mReceivers.put(receiver, filters);
            }
    
            filters.add(entry);
    
            for(int i = 0; i < filter.countActions(); ++i) {
                String action = filter.getAction(i);
                ArrayList<LocalBroadcastManager.ReceiverRecord> entries = (ArrayList)this.mActions.get(action);
                if (entries == null) {
                    entries = new ArrayList(1);
        			//    
                    this.mActions.put(action, entries);
                }
                entries.add(entry);
            }
        }
    }
    
    

    登録するとき、彼はまず放送情報体ReceiverRecordを構築し、私たちが登録した受信情報をReceiverに追加し、Actionを遍歴し、Actionとイベントを関連付け、sendBroadcastを呼び出して放送を送信し、彼はデータを処理した後、分類を開始し、私たちのBundler、Dataなどのデータがあり、実際には最後に呼び出されたコード:
    this.mPendingBroadcasts.add(new LocalBroadcastManager.BroadcastRecord(intent, receivers));
    if (!this.mHandler.hasMessages(1)) {
        this.mHandler.sendEmptyMessage(1);
    }
    

    このセクションでは、このセクションも簡単です.ブロードキャストをmPendingBroadcastsに追加した後、Whatが1のHandlerを送信します.このHandlerは、前に単例を取得した後、構築方法で作成したものです.だから、このwhat=1の判断を見て、彼が最終的に実行した関数はexecutePendingBroadcastsです.コードは多くありません.貼ることができます.
    void executePendingBroadcasts() {
        while(true) {
            HashMap var2 = this.mReceivers;
            LocalBroadcastManager.BroadcastRecord[] brs;
            synchronized(this.mReceivers) {
                int N = this.mPendingBroadcasts.size();
                if (N <= 0) {
                    return;
                }
    
                brs = new LocalBroadcastManager.BroadcastRecord[N];
                this.mPendingBroadcasts.toArray(brs);
                this.mPendingBroadcasts.clear();
            }
            for(int i = 0; i < brs.length; ++i) {
                LocalBroadcastManager.BroadcastRecord br = brs[i];
                int nbr = br.receivers.size();
    
                for(int j = 0; j < nbr; ++j) {
                    LocalBroadcastManager.ReceiverRecord rec = (LocalBroadcastManager.ReceiverRecord)br.receivers.get(j);
                    if (!rec.dead) {
                        rec.receiver.onReceive(this.mAppContext, br.intent);
                    }
                }
            }
        }
    }
    
    

    この2層forループを通じて、彼が最終的に傍受されたブロードキャストメッセージ体brsのデータを取得し、BroadcastRecordを取得し、brを呼び出すことができます.receivers.getは受信オブジェクトrecを取得し、rec.receiverを通過する.onReceive通知は傍受しており,メッセージの送信と受信を実現している.
    全体の設計理念は観察者モードであり、オブジェクトの一対多の関係依存であり、1つのオブジェクトが変化すると、彼のすべての依存者が通知され、自動的に更新される.
    運転完了、オーバー!!!