天天看點

[Android][第一行代碼][第 5 章 廣播機制]

01. 廣播機制簡介

  1. 在一個 IP 網絡範圍中,最大的 IP 位址是被保留作為廣播位址來使用的。比如某個網絡的 IP 範圍是

    192.168.0.xxxx

    子網路遮罩是

    255.255.255.0

    那麼這個網絡的廣播位址就是

    192.168.0.255

    了。廣播資料包會被發送到同一網絡上的所有端口,這樣在該網絡中的每台主機都将會收到這條廣播。
  2. 在 Android 中每個應用可以對自己感興趣的廣播進行注冊,這樣該程式就隻會接收到自己關心的廣播。應用可以自由的發送和接收廣播。

02. 廣播分類

  • 标準廣播
    • 一種完全異步執行的廣播。廣播發出後,所有接收器幾乎同時接收到廣播消息,是以沒有先後順序,效率高,無法被截斷。
  • 有序廣播
    • 一種同步執行的廣播。廣播發出後,同一時刻隻有一個接收器接收到廣播消息,這個接收器執行完畢廣播才會繼續傳遞,是以有先後順序,優先級高的接收器先收到,并且前面的可以截斷正在傳遞的廣播,這樣後面的就無法收到廣播消息了。

03. 注冊廣播

  • 動态注冊
    • 需要使用

      IntentFilter

      類指定相應的

      action

    • 注冊

      解注冊

      成對出現,在

      onCreate

      中進行注冊在

      onDestroy

      中進行解注冊
  • 靜态注冊
    • 需要在功能清單中使用

      intent-filter

      action

      标簽指定
    • 注冊之後為系統

      全局

      的廣播接收器
    • 程式程序

      運作中

      可以接收

      ,程式程序

      完成退出

      無法接收

04. 廣播示例代碼

  1. 動态注冊-監聽網絡變化
    1. 繼承 BroadcastReceiver
      /**
      * 動态廣播監聽網絡變化
      *
      * @author JustDo23
      */
      public class NetworkChangeReceive extends BroadcastReceiver {
      
      @Override
      public void onReceive(Context context, Intent intent) {
        ToastUtil.showShortToast(context, "Network changes.");
        ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
        if (networkInfo != null && networkInfo.isAvailable()) {
          ToastUtil.showShortToast(context, "Network is available.");
        } else {
          ToastUtil.showShortToast(context, "Network is unavailable.");
        }
      }
      
      }
                 
    2. 在 Activity 中注冊與解注冊
      /**
      * 動态廣播監聽網絡變化
      *
      * @author JustDo23
      */
      public class NetworkChangeActivity extends BaseActivity {
      
      private IntentFilter intentFilter;
      private NetworkChangeReceive networkChangeReceive;
      
      @Override
      protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_network_change);
        register();// 注冊廣播
      }
      
      @Override
      protected void onDestroy() {
        super.onDestroy();
        unRegister();// 解注冊廣播
      }
      
      /**
       * 注冊廣播
       */
      private void register() {
        intentFilter = new IntentFilter();
        intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
        networkChangeReceive = new NetworkChangeReceive();
        this.registerReceiver(networkChangeReceive, intentFilter);
      }
      
      /**
       * 解注冊廣播
       */
      private void unRegister() {
        unregisterReceiver(networkChangeReceive);
      }
      
      }
                 
    3. 添權重限
      <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
                 
  2. 靜态注冊-監聽手機開機
    1. 使用 Android Studio 建立廣播接收器
      • 右擊

        選擇

        New

        選擇

        Other

        選擇

        Broadcast Receiver

        進行命名
      • 此操作與手動建立一緻
    2. 功能清單新增
      <receiver
      android:name=".chapter05.CustomReceiver"
      android:enabled="true"
      android:exported="true">
      </receiver>
                 
      • enabled

        屬性表示是否啟用這個廣播接收器
      • exported

        屬性表示是否允許這個廣播接收器接收本程式以外的廣播
    3. 添加

      <intent-filter>

      标簽并指定

      <action>

      标簽資訊
      <receiver
      android:name=".chapter05.CustomReceiver"
      android:enabled="true"
      android:exported="true">
      <intent-filter android:priority="100">
        <action android:name="com.just.first.CUSTOM" />
      </intent-filter>
      </receiver>
                 
      • priority

        指定了廣播的優先級
    4. 添權重限
      <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
                 

05. 發送自定義廣播

  1. 發送标準廣播
  2. 發送有序廣播
    • 發送有序廣播需要指定

      優先級

      ,可以在功能清單中使用

      priority

      指定優先級
    • 前面的廣播可以截斷廣播的傳遞,在

      onReceive()

      方法中調用

      abortBroadcast()

      方法截斷廣播

06. 本地廣播

前面的廣播都屬于系統全局廣播,即發出的廣播可以被其他任何程式接收到,并且程式也可以接收來自其他任何應用的廣播。這樣存在安全問題。Android 引入了一套本地廣播機制,使用本地廣播機制廣播隻能在本應用内部進行發送和接收。主要是使用了一個

LocalBroadcastManager

來對廣播進行管理。

  1. 本地廣播注冊
    private LocalBroadcastReceiver localBroadcastReceiver;
     private LocalBroadcastManager localBroadcastManager;
    
     @Override
     protected void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.activity_local_broadcast);
    
       localBroadcastManager = LocalBroadcastManager.getInstance(this);// 擷取執行個體
       IntentFilter intentFilter = new IntentFilter();
       intentFilter.addAction("com.just.first.LOCAL");
       localBroadcastReceiver = new LocalBroadcastReceiver();// 執行個體化接收器
       localBroadcastManager.registerReceiver(localBroadcastReceiver, intentFilter);// 注冊本地廣播
     }
               
  2. 本地廣播解注冊
    @Override
     protected void onDestroy() {
       super.onDestroy();
       localBroadcastManager.unregisterReceiver(localBroadcastReceiver);
     }
               
  3. 本地廣播發送
    public void sendLocalBroadcast(View view) {
       Intent intent = new Intent("com.just.first.LOCAL");
       localBroadcastManager.sendBroadcast(intent);// 發送本地廣播
     }
               
  4. 重要提示
    • 本地廣播是無法通過靜态注冊的方式來接收的。
    • 靜态注冊主要就是為了讓程式在未啟動的情況下也能接收到廣播。
  5. 本地廣播優勢
    • 可以明确知道正在發送的廣播不會離開我們的程式,不必擔心機密資料洩露。
    • 其他程式無法将廣播發送到我們程式的内部,不必擔心有安全漏洞隐患。
    • 發送本地廣播比發送系統全局廣播更加高效。

07. 重點提示

  1. 注意:開發時不能在

    onReceive()

    方法中添加過多邏輯或者進行任何的耗時操作,因為在廣播接收器中不允許開啟線程的,當

    onReceive()

    方法運作較長時間而沒有結束,程式就會出現 ANR 錯誤。
  2. 廣播是一種可以跨程序的

    通信

    方式,例如我們可以接收系統廣播。
  3. 在靜态廣播接收器及本地廣播接收器中是沒有辦法彈出對話框的。
    android.view.WindowManager$BadTokenException: Unable to add window -- token null is not valid; is your activity running?
               
  4. 在動态廣播接收器中是可以彈出對話框的。
  5. 當在

    BaseActivity

    中注冊廣播進而使得所有子類都動态注冊該廣播的操作中,需要将廣播的

    注冊

    解注冊

    分别放在生命周期的

    onResume()

    onPause()

    中。這樣可以保障隻有處于棧頂的活動才能接收到廣播資訊。

08. 初識 Git

  1. Git 是一個開源的分布式

    版本控制

    工具。
  2. 配置身份
    $ git config --global user.name "JustDo23"
    $ git config --global user.email "[email protected]"
               
  3. 建立代碼倉庫
    $ git init
               
  4. 添加與送出
    $ git add .
    $ git commit -m "describe for commit"
               

09. 小結

  1. 廣播的生命周期簡單了解。
  2. 進一步了解廣播的工作原理。