Android 中的消息傳遞,詳解廣播機制

————————————廣播機制簡介————————————

我們先看一下什麼是廣播機制:

  1. Android中的廣播機制非常靈活,Android中的每個應用程序都可以對自己感興趣的廣播進行註冊,這個程序也只會收到自己所關心的廣播內容,這些廣播可能是來自於系統的,也可能是來自於其他應用程序的。

  2. Android提供了一套完整的API,允許應用程序自由地發送和接受廣播。

  3. Android中的廣播主要可以分爲兩種類型,標準廣播有序廣播

標準廣播(Normal broadcasts):標準廣播是一種 完全異步 執行的廣播,在廣播發出之後,所有的廣播接收器幾乎會在同一時刻接收到這條廣播消息。這種廣播效率比較高,但同時也意味着它是無法被截斷的。

有序廣播(Ordered broadcasts):有序廣播則是一種 同步 執行的廣播,在廣播發出之後,同一時刻只會有一個廣播接收器能夠收到這條廣播消息,當這個廣播接收器中的邏輯執行完畢之後,廣播纔會繼續傳遞。

————————————接受系統廣播————————————

Android內置了很多系統級別的廣播,可以在應用程序中通過監聽這些廣播來得到各種系統的狀態信息。

手機開機完成後會發出一條廣播,電池的電量發生變化會發出一條廣播,時間改變也會發出一條廣播……如果想要接受到這些廣播,就需要使用廣播接收器。

廣播接收器可以自由地對自己感興趣的廣播進行註冊,當有相應的廣播發出時,廣播接收器就能夠收到該廣播,並在內部處理相對應的邏輯。

我們來看一下兩種註冊方式:

  • 在代碼中註冊(動態註冊)
  • 在 AndroidManifest.xml 中註冊(靜態註冊)

創建廣播接收器只需要新建一個類,讓它繼承自BroadcastReceiver,並重寫父類的onReceiver()方法。當有消息通過廣播傳遞過來時,onReceive()方法就會得到執行。

讓我們先看第一種註冊,動態註冊監聽網絡變化:

看代碼:

public class MainActivity extends AppCompatActivity {
    private IntentFilter intentFilter;
    private NetworkChangeReceiver networkChangeReceiver;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);


        intentFilter = new IntentFilter();
        //爲過濾器添加處理規則
        intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
        networkChangeReceiver = new NetworkChangeReceiver();
        //註冊廣播接收器
        registerReceiver(networkChangeReceiver, intentFilter);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        //動態的廣播接收器最後一定要取消註冊
        unregisterReceiver(networkChangeReceiver);
    }

    //自定義內部類,繼承自BroadcastReceiver
    public class NetworkChangeReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            //實現onReceive()方法的邏輯
            Toast.makeText(context, "網絡狀態改變", Toast.LENGTH_SHORT).show();
        }
    }
}

接下來讓我們分析一下這段代碼:

NetworkChangeReceiver extends BroadcastReceiver 這段代碼就是在MainActivity中定義了一個內部類,並且繼承了BroadcastReceiver,然後重寫了父類的onReceive

IntentFilteraddAction() 方法中添加了一個值爲 android.net.conn.CONNECTIVITY_CHANGEaction,用於接收系統對網絡狀態改變而發出的一條廣播。(廣播接收器想要監聽什麼廣播,就在這裏添加相應的action

調用 registerReceiver() 方法對廣播接收器進行註冊,將 networkChangeReceiver繼承了BroadcastReceiver) 和 IntentFilter 的實例傳遞進去即可。

最後要記得,動態註冊的廣播接收器一定都要取消註冊才行。通過調用 unregisterReceiver() 方法取消註冊。

這樣我們看起來這一段代碼還是十分簡單的。

我們現在只是提醒網絡發生變換,但是這是不夠人性化的,我們應該能直接準確的告訴用戶有網絡還是沒有網絡,這樣我們對上面的代碼進行優化:

修改 NetworkChangeReceiver 的 onReceiver() 方法,使之能夠準確告訴用戶當前網絡狀態:

Android系統規定,如果程序需要訪問系統關鍵信息,必須在配置文件中聲明權限纔可以,否則程序直接崩潰。

這裏查詢網絡狀態需要聲明權限,打開AndroidManifest.xml文件,爲添加權限(之前),代碼如下:

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

修改 NetworkChangeReceiver 中的代碼:

public class NetworkChangeReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        //connectivityManger是一個系統服務類,專門用於管理網絡連接
        ConnectivityManager connectivityManager = (ConnectivityManager)
        getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
        //調用NetworkInfo的isAvailable()方法判斷是否聯網
        if(networkInfo != null && networkInfo.isAvailable()){
            Toast.makeText(context,"網絡已連接",Toast.LENGTH_SHORT).show();
        }else{
            Toast.makeText(context,"網絡不可用",Toast.LENGTH_SHORT).show();
        }
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章