Android廣播的詳解

廣播簡介:

爲什麼說 Android 中的廣播機制更加靈活呢?這是因爲 Android 中的每個應用程序都可以對自己感興趣的廣播進行註冊,這樣該程序就只會接受自己所關心的廣播內容,這些廣播內容可能是來自於系統,也可能是來自於其他應用程序的。Android 提供了一整套的 API,允許應用程序自由地發送和接受廣播。

廣播分爲兩大類:

  • 標準廣播(Normal broadcasts)是一種完全異步執行的廣播,在廣播發出之後,所有的廣播接收器幾乎都會在同一時刻接受到這條廣播消息,因此它們之間沒有任何先後順序可言,這種廣播的效率會比較高,但同時也意味着它是無法被攔截的。

  • 有序廣播(Ordered broadcasts) 則是一種同步執行的廣播,在廣播發出之後,同一時刻只會有一個廣播接收器能夠收到這條廣播消息,當這個廣播接收器中的邏輯執行完畢後,廣播纔會繼續傳遞。所以此時的廣播接受器是有先後順序的,優先級高的廣播接收器就可以先收到廣播消息,並且前面的廣播接收器還可以截斷正在傳遞的廣播,這樣後面的廣播接收器就無法收到廣播消息了。

1.接受系統廣播

Android 內置了很多系統級別的廣播,我們可以在應用中通過監聽這些廣播來得到各種系統的狀態信息。比如手機開機後會發送一條廣播,電池的電量發生變化會發出一條廣播,時間或時區發生改變也會發出一條廣播等等。如果想要接受這些廣播,就需要使用廣播接收器。

1.1註冊廣播方式一般有兩種:

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

1.1.1 動態註冊監聽網絡變化

代碼如下:
權限

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

    private  NetWorkChangeReceiver netWorkChangeReceiver;
    private IntentFilter intentFilter;

  private void init() {

         intentFilter = new IntentFilter();
         intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
         netWorkChangeReceiver = new NetWorkChangeReceiver();
         //註冊廣播
        registerReceiver(netWorkChangeReceiver,intentFilter);
    }




    private class NetWorkChangeReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            //系統服務類
            ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);

            NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
            //判斷網絡是否可用
            if (activeNetworkInfo!=null && activeNetworkInfo.isAvailable()){
                Toast.makeText(BroadCastsActivity.this,"網絡可用",Toast.LENGTH_SHORT).show();

            }else {
                Toast.makeText(BroadCastsActivity.this,"網絡不可用",Toast.LENGTH_SHORT).show();

            }

        }
    }


    @Override
    protected void onDestroy() {
        super.onDestroy();
        //銷燬廣播
        unregisterReceiver(netWorkChangeReceiver);
    }

1.1.2 靜態註冊廣播實現開機啓動:

動態註冊的廣播接收器可以自由地控制註冊與註銷,在靈活性方面有很大的優勢,但是它也存在着一個缺點,即必須要在程序啓動之後才能接受到廣播,因爲註冊的邏輯是寫在 onCreate()方法中的。那麼有沒有什麼方法可以讓程序在未啓動的情況下就能接受到廣播呢?這就需要使用靜態註冊方式了。

我們將廣播接受器命名爲 MyReceiver;

  • Export 屬性表示是否允許這個廣播接收器接受本程序以外的廣播;
  • Enable 屬性表示是否啓用這個廣播接受器;

我們使用 Android的快捷方式創建廣播接收器,因此註冊被自動完成了,打開 AndroidManifest.xml文件看一下:

   <receiver
            android:name=".service.MyReceiver"
            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"/>

注意:不要在 onReceive()方法中添加過多的邏輯或者進行任何的耗時操作,因爲在廣播接收器中是不允許開啓線程的,當onReceive()方法運行了較長時間而沒有結束時,程序就會報錯。因此廣播接收器更多的是扮演一種打開程序其它組件的角色,比如創建一條狀態欄通知,或者啓動一個服務等。



作者:因爲我的心
鏈接:https://www.jianshu.com/p/53e6abd8bfc7
來源:簡書
著作權歸作者所有。商業轉載請聯繫作者獲得授權,非商業轉載請註明出處。

/**
 * 廣播接受器
 */
public class MyReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {


        Toast.makeText(context,"開機廣播",Toast.LENGTH_LONG).show();


    }
}

2.1發送自定義廣播

2.1.1 發送標準廣播

代碼如下:
註冊廣播

 <receiver
            android:name=".service.MyBroadcastReceiver"
            android:enabled="true"
            android:exported="true">

            <intent-filter>
                <action android:name="com.function.luo.MyBroadcastReceiver" />
            </intent-filter>
  </receiver>

重寫廣播方法:

public class MyBroadcastReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        Toast.makeText(context,"發送標準廣播",Toast.LENGTH_LONG).show();
    }
}

調用廣播方法:

  Intent intent = new Intent("com.function.luo.MyBroadcastReceiver");
                 sendBroadcast(intent);

2.1.2 發送有序廣播

廣播是一種跨進程的通信方式,這一點從前面接受系統廣播的時候就可以看出來了。因此在我們應用程序內發出的廣播,其它應用程序也是可以接受的。

//發送有序廣播
 Intent intent = new Intent("com.function.luo.MyBroadcastReceiver");
                 sendOrderedBroadcast(intent,null);

第一個參數是 Intent;
第二個參數是一個與權限相關的字符串,這裏傳 null 就行了

  <receiver
            android:name=".service.MyBroadcastReceiver"
            android:enabled="true"
            android:exported="true">

            <intent-filter
                android:priority="100"
                >
                <action android:name="com.function.luo.MyBroadcastReceiver" />
            </intent-filter>
        </receiver>

android:priority="100" 設置優先級,優先級較高的廣播接收器就可以先收到廣播。

public class MyBroadcastReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        Toast.makeText(context,"發送標準廣播",Toast.LENGTH_LONG).show();
        //攔截廣播
        abortBroadcast();
    }
}

在onReceive()方法中調用了 abortBroadcast()方法,就表示這條廣播截斷,後面的廣播接收器無法再接受到這條廣播。

3.1 使用本地廣播

簡介:

前面我們發送和接受的廣播全部屬於系統全局廣播,即發出的廣播可以被其它任何應用程序接收到,並且我們也可以接受來自於其它任何應用程序的廣播。

爲了解決廣播安全性問題,Android 引入了一套本地廣播機制,使用這個機制發出的廣播只能在應用程序內部進行傳遞,並且廣播接受器也只能接受來自本應用程序發出的廣播,這樣所有的安全性問題就都不存在了。

初始化廣播:

  private LocalBroadcastManager localBroadcastManager;

    private void init() {
        //獲取實例
        localBroadcastManager = LocalBroadcastManager.getInstance(this);

        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction("om.function.luo.LOCAL_BROADCAST");
        LocalReceiver localReceiver = new LocalReceiver();
        localBroadcastManager.registerReceiver(localReceiver, intentFilter);
        
    }

發送本地廣播

 Intent intent = new Intent("om.function.luo.LOCAL_BROADCAST");
        localBroadcastManager.sendBroadcast(intent);

重寫廣播接受方法

    private class LocalReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            Toast.makeText(context, "本地廣播.....", Toast.LENGTH_LONG).show();
        }
    }

注意:

本地廣播是無法通過靜態註冊的方式來接收的,其實這也完全可以理解,因爲靜態註冊主要是爲了讓程序在未啓動的情況下也能接受到廣播,而發送本地廣播時,我們的程序已經啓動了,因此也完全不需要使用靜態註冊的功能。

本地廣播的優勢

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

廣播常用的地方:

類似 QQ強制下線功能,出現一個彈窗,殺死所有 Activity,強制進入登錄頁面(可以選用,靜態廣播,動態廣播或者本地廣播)。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章