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

01. 廣播機制簡介

一個 IP 網絡范圍中,最大的 IP 地址被保留作為廣播地址來使用的。比如某個網絡的 IP 范圍是 192.168.0.xxxx 子網掩碼是 255.255.255.0 那麼這個網絡的廣播地址就是 192.168.0.255 瞭。廣播數據包會被發送到同一網絡上的所有端口,這樣在該網絡中的每臺主機都將會收到這條廣播。 在 Android 中每個應用可以對自己感興趣的廣播進行註冊,這樣該程序就隻會接收到自己關心的廣播。應用可以自由的發送接收廣播。

02. 廣播分類

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

03. 註冊廣播

動態註冊
需要使用 IntentFilter 類指定相應的 action 註冊與解註冊成對出現,在onCreate中進行註冊在onDestroy中進行解註冊 靜態註冊
需要在功能清單中使用 intent-filter 及 action 標簽指定 註冊之後為系統全局的廣播接收器 程序進程運行中則可以接收,程序進程完成退出則無法接收

04. 廣播示例代碼

動態註冊-監聽網絡變化

繼承 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.");
  }
}

}

在 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);
}

}

添加權限

靜態註冊-監聽手機開機

使用 Android Studio 創建廣播接收器

右擊 選擇 New 選擇 Other 選擇 Broadcast Receiver 進行命名 此操作與手動創建一致

功能清單新增


enabled 屬性表示是否啟用這個廣播接收器 exported 屬性表示是否允許這個廣播接收器接收本程序以外的廣播

添加 標簽並指定 標簽信息



  

priority 指定瞭廣播的優先級

添加權限

05. 發送自定義廣播

發送標準廣播

sendBroadcast(new Intent("com.just.first.CUSTOM"));// Intent 指定 action

發送有序廣播

sendOrderedBroadcast(new Intent("com.just.first.CUSTOM"), null);// 第二參數是一個與權限相關的字符串

發送有序廣播需要指定優先級,可以在功能清單中使用 priority 指定優先級 前面的廣播可以截斷廣播的傳遞,在 onReceive() 方法中調用 abortBroadcast() 方法截斷廣播

06. 本地廣播

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

本地廣播註冊

 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);// 註冊本地廣播
 }

本地廣播解註冊

 @Override
 protected void onDestroy() {
   super.onDestroy();
   localBroadcastManager.unregisterReceiver(localBroadcastReceiver);
 }

本地廣播發送

 public void sendLocalBroadcast(View view) {
   Intent intent = new Intent("com.just.first.LOCAL");
   localBroadcastManager.sendBroadcast(intent);// 發送本地廣播
 }

重要提示

本地廣播是無法通過靜態註冊的方式來接收的。 靜態註冊主要就是為瞭讓程序在未啟動的情況下也能接收到廣播。

本地廣播優勢

可以明確知道正在發送的廣播不會離開我們的程序,不必擔心機密數據泄露。 其他程序無法將廣播發送到我們程序的內部,不必擔心有安全漏洞隱患。 發送本地廣播比發送系統全局廣播更加高效

07. 重點提示

註意:開發時不能onReceive() 方法中添加過多邏輯或者進行任何的耗時操作,因為在廣播接收器中不允許開啟線程的,當 onReceive() 方法運行較長時間而沒有結束,程序就會出現 ANR 錯誤。

廣播是一種可以跨進程通信方式,例如我們可以接收系統廣播。

靜態廣播接收器本地廣播接收器中是沒有辦法彈出對話框的。

android.view.WindowManager$BadTokenException: Unable to add window -- token null is not valid; is your activity running?

動態廣播接收器中是可以彈出對話框的。

當在 BaseActivity 中註冊廣播從而使得所有子類都動態註冊該廣播的操作中,需要將廣播的註冊與解註冊分別放在生命周期的 onResume() 與 onPause() 中。這樣可以保障隻有處於棧頂的活動才能接收到廣播信息。

08. 初識 Git

Git 是一個開源分佈式版本控制工具

配置身份

$ git config --global user.name "JustDo23"
$ git config --global user.email "JustDo_23@163.com"

創建代碼倉庫

$ git init

添加與提交

$ git add .
$ git commit -m "describe for commit"

09. 小結

廣播的生命周期簡單瞭解。 進一步瞭解廣播的工作原理。

You May Also Like