Android筆記-四大組件之Broadcast Receiver

簡介

Broadcast Receiver,即廣播接收器,顧名思義,通過廣播的方式進行消息傳遞。

分類

  • 標準廣播
    這是一種完全異步執(zhí)行的廣播,這種廣播發(fā)出后,所有接收器之間幾乎同時收到消息,它們之間沒有任何順序可言,因此這種廣播效率比較高,無法被攔截。

  • 有序廣播
    這是一種同步執(zhí)行的廣播,這種廣播發(fā)出后,各接收器是按照注冊的優(yōu)先級的順序來進行接收的,優(yōu)先級高的先接收,優(yōu)先級低的后接收,并且可以被中斷,一旦被中斷則后續(xù)接收器則無法接收到此消息了。

使用方式

廣播使用方式基本相同,在BroadcastReceiver類中的onReceive()方法中處理接收器邏輯,但是不能進行耗時操作,因為在這里不允許開啟線程的;另外廣播是有優(yōu)先級的,優(yōu)先級高的先收到廣播。

  • 標準廣播
    • 系統(tǒng)廣播

      • 靜態(tài)注冊

      第一步,編寫廣播接收器處理代碼,該類繼承自BroadcastReceiver類

      public class BootCompleteReceiver extends BroadcastReceiver {
      
          @Override
          public void onReceive(Context context, Intent intent) {
              Toast.makeText(context, "Boot Complete", Toast.LENGTH_LONG).show();
          }
      }
      

      第二步,在manifest文件中聲明

      <receiver
          android:name=".broadcast.BootCompleteReceiver"
          android:enabled="true"
          android:exported="true">
          <intent-filter>
              <action android:name="android.intent.action.BOOT_COMPLETED" />
          </intent-filter>
      </receiver>
      

      第三步,添加權限

      <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
      

      靜態(tài)注冊的方式是通過xml在manifest文件中進行注冊,其特點是:在程序未啟動的情況也能接收到廣播消息,并且無法取消注冊。

      • 動態(tài)注冊

      第一步,編寫廣播接收器處理代碼,該類繼承自BroadcastReceiver類

      public class NetworkChangeReceiver extends BroadcastReceiver {
          @Override
          public void onReceive(Context context, Intent intent) {
      
              //get the state of network
              ConnectivityManager connectivityManager = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
              NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
      
              String state;
              if (networkInfo != null && networkInfo.isAvailable()) {
                  state = "available";
              } else {
                  state = "unavailable";
              }
      
              Toast.makeText(context, "Network is " + state, Toast.LENGTH_LONG).show();
          }
      }
      

      第二步,在Activity 中注冊及取消

      public class BroadcastDynamicSystemActivity extends AppCompatActivity {
      
          private IntentFilter intentFilter;
          private NetworkChangeReceiver networkChangeReceiver;
      
          public static void startAction(Context context) {
              context.startActivity(new Intent(context, BroadcastDynamicSystemActivity.class));
          }
      
          @Override
          protected void onCreate(Bundle savedInstanceState) {
              super.onCreate(savedInstanceState);
              setContentView(R.layout.activity_broadcast_dynamic_system);
      
              //register network change broadcast receiver
              this.intentFilter = new IntentFilter();
              this.intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
              this.networkChangeReceiver = new NetworkChangeReceiver();
      
              registerReceiver(this.networkChangeReceiver, this.intentFilter);
          }
      
          @Override
          protected void onDestroy() {
              super.onDestroy();
      
              //unregister network change broadcast receiver
              unregisterReceiver(this.networkChangeReceiver);
          }
      }
      

      第三步,在manifest文件中添加網(wǎng)絡訪問權限

      <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
      

      動態(tài)注冊的流程是:先編寫廣播接收器的處理方法(繼承自BroadcastReceiver類),然后在應用的地方進行注冊和取消注冊。這種方式的特點是:
      1. 只有動態(tài)注冊代碼執(zhí)行了才會接收廣播,沒執(zhí)行是不會收到廣播的;
      2. 需要實時取消注冊,以防內(nèi)存泄漏。

    • 自定義廣播

      • 標準廣播

      第一步,編寫廣播接收器處理代碼,該類繼承自BroadcastReceiver類

      public class MyStandardBroadcastReceiver extends BroadcastReceiver {
          @Override
          public void onReceive(Context context, Intent intent) {
              Toast.makeText(context, "My Standard Broadcast Receiver", Toast.LENGTH_LONG).show();
          }
      }
      

      第二步,在manifest中注冊(此為靜態(tài)注冊方式注冊,亦可動態(tài)方式注冊)

      <receiver android:name=".broadcast.MyStandardBroadcastReceiver">
          <intent-filter>
              <action android:name="com.example.broadcast.MY_BROADCAST" />
          </intent-filter>
      </receiver>
      

      第三步,發(fā)送自定義廣播

      sendBroadcast(new Intent("com.example.broadcast.MY_BROADCAST"));
      

      這里需要注意的是廣播的action name必須一致。

      • 有序廣播

      第一步,編寫廣播接收器處理代碼,該類繼承自BroadcastReceiver類

      public class MyOrderedBroadcastReceiver extends BroadcastReceiver {
          @Override
          public void onReceive(Context context, Intent intent) {
              Toast.makeText(context, "My Ordered Broadcast Receiver", Toast.LENGTH_LONG).show();
              
              //中斷傳播
              abortBroadcast();
          }
      }
      

      第二步,在manifest中注冊(此為靜態(tài)方式注冊,亦可動態(tài)注冊)

      <receiver android:name=".broadcast.MyOrderedBroadcastReceiver">
          <intent-filter android:priority="100">
              <action android:name="com.example.broadcast.MY_BROADCAST" />
          </intent-filter>
      </receiver>
      

      第三步,發(fā)送自定義廣播

      sendOrderedBroadcast(new Intent("com.example.broadcast.MY_BROADCAST"), null);
      

      有序廣播和標準廣播使用方式上唯一區(qū)別在于發(fā)送方法不同以及有序廣播可以通過abortBroadcast()方法來中斷廣播的傳遞。

  • 本地廣播

    標準廣播都是全局的,即不僅本應用會接收而且其他應用也可以接收,因此如果一直發(fā)送標準廣播不僅會對系統(tǒng)造成污染,而且也會帶來安全隱患,為了解決這些問題,Android系統(tǒng)引入了本地廣播機制。

    • 使用方法
      第一步,編寫廣播接收器處理代碼,該類繼承自BroadcastReceiver類

      public class LocalBroadcastReceiver extends BroadcastReceiver {
      
          @Override
          public void onReceive(Context context, Intent intent) {
              Toast.makeText(context, "Local Broadcast Receiver", Toast.LENGTH_LONG).show();
          }
      }
      

      第二步,發(fā)送廣播

      private IntentFilter intentFilter;
      private LocalBroadcastReceiver localBroadcastReceiver;
      private LocalBroadcastManager localBroadcastManager;
      
      @Override
      protected void onCreate(Bundle savedInstanceState) {
          ……
          
          this.intentFilter = new IntentFilter();
          this.intentFilter.addAction("com.example.broadcast.MY_LOCAL_BROADCAST");
          this.localBroadcastManager = LocalBroadcastManager.getInstance(this);
          this.localBroadcastReceiver = new LocalBroadcastReceiver();
          this.localBroadcastManager.registerReceiver(this.localBroadcastReceiver, this.intentFilter);
      }
      
      @Override
      protected void onDestroy() {
          super.onDestroy();
          this.localBroadcastManager.unregisterReceiver(this.localBroadcastReceiver);
      }
      
      //發(fā)送本地廣播
      this.localBroadcastManager.sendBroadcast(new Intent("com.example.broadcast.MY_LOCAL_BROADCAST"));
      
    • 特點

      • 消息只在本應用內(nèi)進行傳遞;
      • 無法通過靜態(tài)注冊的方式進行注冊;
      • 比系統(tǒng)全局廣播更高效。

總結

  • 當需要在程序未啟動就接收廣播消息時,使用靜態(tài)注冊方式注冊廣播;
  • 當需要靈活控制接收或者不接受廣播消息時,使用動態(tài)注冊方式注冊廣播;
  • 當廣播消息僅在本應用內(nèi)部進行傳遞,使用本地廣播更高效更安全;
  • 當需要對廣播消息對傳遞進行順序控制時,使用有序廣播廣播。
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容