從0系統學Android--5.1 廣播機制
本系列文章目錄:更多精品文章分類
本系列持續更新中…. 初級階段內容參考《第一行代碼》
第五章:全局大喇叭---詳解廣播機制
5.1 廣播機制簡介
Android 中每個應用程序都可以對自己感興趣的廣播進行註冊,這樣當註冊的廣播發出時,應用程序就會接受到。這些廣播可能來自系統,也可能來自其他應用程序。
接受廣播需要用到Broadcast Receiver 廣播接收器。
Android 中的廣播分為兩種:標準廣播和有序廣播。
標準廣播:是一種完全異步執行的廣播,在廣播發出後幾乎所有的接收器都會在同一時刻收到廣播消息。因此它們之間沒有任何的先後順序,這種廣播效率比較高,但同時意味著不能被截斷。
有序廣播:是一種同步執行的廣播,在廣播發出後,同一時刻只有一個廣播接收器能夠收到這條廣播消息,當這個廣播接收器中的邏輯執行完畢後廣播才會繼續傳播。有序廣播是有先後順序的,優先級高的會優先接受到廣播並且可以截斷正在傳遞的廣播。
5.2 接受系統廣播
Android 系統內置了許多的系統級別的廣播,我們可以通過這些廣播來獲取手機的一些狀態。比如手機開機會發送一條廣播,電池電量發生變化會發送廣播,時間或者時區發生改變會發送廣播等等。
5.2.1 動態註冊監聽網絡變化
註冊廣播的方式有兩種:一種是在代碼中註冊稱為動態註冊,另一種是在 AndroidManifest.xml 中註冊稱為靜態註冊。
如何才能接受到廣播呢?首先要創建一個廣播接收器。
新建一個類,讓他繼承 BoradcastReceiver 並重寫 onReceive() 方法,當接受到廣播後就會執行 onReceive() 方法,這樣一個簡單的廣播包接收器就創建好了。
下面來具體實踐一下:
<code>public class NetChangeActivity extends AppCompatActivity {
NetWorkChangeReceiver netWorkChangeReceiver;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_ui);
IntentFilter intentFilter = new IntentFilter();
// 每當網絡狀態發生改變的時候都會接受到廣播(有網絡了,沒有網絡了,切換到 WiFi了)
intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
netWorkChangeReceiver = new NetWorkChangeReceiver();
registerReceiver(netWorkChangeReceiver,intentFilter);
}
class NetWorkChangeReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context,"網絡狀態發生變化",Toast.LENGTH_SHORT).show();
}
}
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(netWorkChangeReceiver);
}
}/<code>
其實具體過程很簡單,步驟:
- 新建一個廣播接收器
- 通過 IntentFilter 來指定要接受的廣播
- registerReceiver() 來註冊廣播
- 需要取消註冊
進一步編寫,告訴用戶當前是有網絡還是沒有網絡
<code> ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
if (networkInfo!=null && networkInfo.isAvailable()){
Toast.makeText(context,"網絡可用",Toast.LENGTH_SHORT).show();
}else {
Toast.makeText(context,"網絡不可用",Toast.LENGTH_SHORT).show();
}/<code>
主要是通過 ConnectivityManager 這個專門用於管理網絡的服務類來實現的。
注意這裡需要訪問系統的網絡狀態,需要聲明權限,在 AndroidManifest.xml 中
<code> <uses-permission>/<code>
5.2.2 靜態註冊實現開機啟動
動態註冊廣播接受有一個缺點就是必須程序運行了才可以接受到廣播,原因很簡單,只有我們打開了對應的程序頁面運行了註冊的邏輯才可以接受到廣播。
那麼怎麼樣可以讓程序在沒有啟動的情況下就能接受到廣播呢?這就需要靜態註冊了。
靜態註冊可以讓程序沒有啟動就接受到廣播消息
代碼實現:首先我們新建一個 Java 類繼承自 BroadcastReceiver
<code>public class BootCompleteReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context,"開機完成",Toast.LENGTH_SHORT).show();
}
}/<code>
很簡單,當接收到開機廣播後就Toast 一下就可以了。下面開始進行靜態註冊,到 AndroidManifest.xml 中,其實和註冊 Activity 非常相似
<code> <receiver> android:enabled="true"
android:exported="true">
<intent-filter>
<action>
/<intent-filter>
/<receiver>/<code>
重點是 exported 設置為 true 表示可以接受本程序之外的廣播,不然就接受不到程序外的廣播了,因為要接受開機廣播,不是我們的程序自己發出的所以要設置為 true 。enable 的意思就是啟用這個廣播接收器。
通過 action 標籤指定要接受的廣播。接受開機廣播需要權限
<code> <uses-permission>/<code>
好了,這樣在開機的時候就會接受到廣播了。
注意: 廣播接收器 onReceive() 方法裡面不要做太多的邏輯或者任何的耗時操作,因為在廣播接收器中是不允許開啟線程的,並且如果 onReceive() 方法運行了較長時間而沒有結束的話程序就會報錯。因此廣播接收器扮演的是一種打開程序其他組件的角色,比如創建狀態欄通知,或者啟動一個服務等等。
閱讀更多 Android程序猿 的文章