Androidローカル放送使用とソース分析

18199 ワード

ローカル放送の基礎紹介
  • LocalBroadcastManagerは、Android supportパッケージが提供するツールで、同じアプリケーション内の異なるコンポーネント間でBroadcastを送信して通信するために使用されます.
  • LocalBroadcastManagerを使用するメリットは
  • です.
  • で送信されたブロードキャストは、自分のアプリ内でしか伝播せず、他のアプリに漏洩せず、プライバシー情報が漏洩しないことを確保します.
  • 他のAppは、他のAppに干渉されずに自分のAppにブロードキャストを送信できません.
  • は、グローバルブロードキャストよりも低コストで効率的です.

  • 使用方法
  • 単利エンティティ
  • を取得する.
    val lbm = LocalBroadcastManager.getInstance(this)
    
  • はローカル放送と同様に
  • に登録する必要がある.
    val broadcastReceiver: BroadcastReceiver = object : BroadcastReceiver() {
                override fun onReceive(context: Context, intent: Intent) {
                    Log.e(TAG, "       ")
                }
            }
    lbm.registerReceiver(broadcastReceiver, IntentFilter("LOCAL_ACTION"))
    
  • 解縛方法
  • LocalBroadcastManager.getInstance(this).unregisterReceiver(broadcastReceiver)
    
  • ブロードキャスト
  • を送信
     lbm.sendBroadcast(Intent("LOCAL_ACTION"))
    

    ここでは、ローカル放送は動的に登録するしかなく、グローバル放送のようにAndroidManifestに登録することはできないと設定しています.その設計の初心は外部放送を受け入れないからです.
    グローバルブロードキャストとローカルブロードキャストの比較:
    ローカル放送はグローバル放送より速く、Android原生に最も近い.複数のsupportバージョンの反復を経て、安定性と互換性が最も優れています.通信セキュリティの機密性と通信効率は、グローバルブロードキャストよりもはるかに高い.
    ローカルブロードキャストソース解析
  • ローカルブロードキャストは、オブザーバーモード
  • を用いる.
    オブザーバモード:オブジェクト間の一対のマルチ依存性が定義され、オブジェクトがステータスを変更すると、すべての依存者が通知され、自動的に更新されます.
  • まずregisterソース
  • を見てみましょう
    public void registerReceiver(@NonNull BroadcastReceiver receiver,
                @NonNull IntentFilter filter) {
            synchronized (mReceivers) {
            	//      
                ReceiverRecord entry = new ReceiverRecord(filter, receiver);
                ArrayList<ReceiverRecord> filters = mReceivers.get(receiver);
                if (filters == null) {
                    filters = new ArrayList<>(1);
                    //         
                    mReceivers.put(receiver, filters);
                }
                filters.add(entry);
                for (int i=0; i<filter.countActions(); i++) {
                    String action = filter.getAction(i);
                    ArrayList<ReceiverRecord> entries = mActions.get(action);
                    if (entries == null) {
                        entries = new ArrayList<ReceiverRecord>(1);
                        //       
                        mActions.put(action, entries);
                    }
                    entries.add(entry);
                }
            }
        }
    

    ReceiverRecordブロードキャスト情報エンティティを構築し、Actionsに追加
  • sendBroadcastソースコード
  • public boolean sendBroadcast(@NonNull Intent intent) {
            synchronized (mReceivers) {
                    if (receivers != null) {
                        for (int i=0; i<receivers.size(); i++) {
                            receivers.get(i).broadcasting = false;
                        }
                        mPendingBroadcasts.add(new BroadcastRecord(intent, receivers));
                        if (!mHandler.hasMessages(MSG_EXEC_PENDING_BROADCASTS)) {
                        	//       handler      executePendingBroadcasts  
                        	//      Handler      
                            mHandler.sendEmptyMessage(MSG_EXEC_PENDING_BROADCASTS);
                        }
                        return true;
                    }
                }
            }
            return false;
        }
    
  • 実際にブロードキャストを送信するソースコード
  • void executePendingBroadcasts() {
            while (true) {
                final BroadcastRecord[] brs;
                synchronized (mReceivers) {
                    final int N = mPendingBroadcasts.size();
                    if (N <= 0) {
                        return;
                    }
                    brs = new BroadcastRecord[N];
                    mPendingBroadcasts.toArray(brs);
                    mPendingBroadcasts.clear();
                }
                for (int i=0; i<brs.length; i++) {
                    final BroadcastRecord br = brs[i];
                    final int nbr = br.receivers.size();
                    for (int j=0; j<nbr; j++) {
                        final ReceiverRecord rec = br.receivers.get(j);
                        if (!rec.dead) {
                        	//        onReceive   
                            rec.receiver.onReceive(mAppContext, br.intent);
                        }
                    }
                }
            }
        }
    

    ローカルブロードキャスト手順:
  • sendBroadcastを呼び出し、ブロードキャストIntent
  • を伝送する
  • は、IntentのActionインデックスブロードキャスト配列リストを用いて、ブロードキャストエンティティをインデックスする.
  • は、Handlerを介してプライマリスレッドにコールバックし、executePendingBroadcastsを介してブロードキャストを実行する.
  • は、登録されたBroadRecoverのonReceiveメソッドを呼び出して、ブロードキャストトリガコンテンツを完了する.

  • 注意:sendBroadcastを呼び出すと、handlerを介してプライマリ・スレッドに移動したため、ブロードキャストは常にプライマリ・スレッドに受信されます.sendBroadcastSyncメソッドを呼び出してブロードキャストを送信する場合、受信したブロードキャストは、ブロードキャストが送信されるスレッドにある.
    ローカルブロードキャストは,様々なメッセージ伝送機構に広く用いられる観察者モードを用いて情報のトリガを達成した.