Android08-廣播機(jī)制

廣播的類(lèi)型:

  1. 標(biāo)準(zhǔn)廣播:完全異步執(zhí)行的廣播,這也意味著,在廣播發(fā)出之后,所有的廣播接收器幾乎會(huì)在同一時(shí)刻接收到廣播消息,因此它們之間沒(méi)有先后順序可言,這種廣播的效率會(huì)比較高,標(biāo)準(zhǔn)廣播的流程圖如下所示。圖片來(lái)自第一行代碼


    2017-04-07_14-07-37.png
  1. 有序廣播:一種同步執(zhí)行的廣播,在廣播發(fā)出之后,同一時(shí)刻只有一個(gè)廣播接收器能夠收到這條廣播消息。當(dāng)這個(gè)廣播接收器中的邏輯執(zhí)行完畢之后,廣播才會(huì)繼續(xù)傳遞。


    2017-04-07_14-09-52.png

1. 接收系統(tǒng)廣播

Android內(nèi)置了很多系統(tǒng)級(jí)別的廣播,比如電池電量,時(shí)區(qū)時(shí)區(qū)、開(kāi)關(guān)機(jī)、等狀態(tài)變化時(shí)都可以發(fā)送系統(tǒng)廣播。

  • 廣播接收器的簡(jiǎn)介

廣播接收器可以自定義對(duì)某些廣播進(jìn)行注冊(cè),當(dāng)收到注冊(cè)的廣播時(shí)能夠在內(nèi)部做相應(yīng)的邏輯處理。

  • 如何創(chuàng)建一個(gè)廣播接收器:

新建一個(gè)類(lèi),讓它繼承自Broadcast-Receiver,并重寫(xiě)父類(lèi)的onReceive()方法。這樣當(dāng)有廣播進(jìn)來(lái)的時(shí),就會(huì)調(diào)用onRecevier()方法。

  • 注冊(cè)廣播的方式:
  1. 在代碼中注冊(cè):也稱(chēng)為動(dòng)態(tài)注冊(cè),動(dòng)態(tài)注冊(cè)的廣播接收器在處理完業(yè)務(wù)之后都要取消注冊(cè)。
  2. 在AndroidManifest.xml中注冊(cè):也稱(chēng)為靜態(tài)注冊(cè)。
    注:動(dòng)態(tài)注冊(cè)雖然靈活性高,但是需要在打開(kāi)程序的情況下才可接收到廣播。所以當(dāng)需要實(shí)現(xiàn)開(kāi)啟啟動(dòng)時(shí)就需要用到靜態(tài)注冊(cè)了。另外在注冊(cè)前都需要在配置文件中聲明權(quán)限,否則直接崩潰
```

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.anwser_mac.broadcasttest">
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
```

  • 使用廣播的注意點(diǎn)

1.如果是靜態(tài)注冊(cè)廣播的話(huà)需要在配置文件說(shuō)明,如果是通過(guò)系統(tǒng)創(chuàng)建的話(huà)則系統(tǒng)會(huì)自動(dòng)添加

<receiver

android:name=".BootCompleteReceiver"
android:enabled="true"
android:exported="true">
</receiver>

2.動(dòng)態(tài)廣播接收器在處理完業(yè)務(wù)之后要記得取消注冊(cè)。
3.涉及系統(tǒng)權(quán)限的廣播都要在配置文件做聲明。
4.廣播接收器中不允許開(kāi)啟線(xiàn)程,因此不能夠在onReceiver()方法中處理過(guò)多邏輯或耗時(shí)操作,一般廣播接收器扮演的是打開(kāi)程序其他組件的角色,比如創(chuàng)建狀態(tài)欄通知,或者啟動(dòng)一個(gè)服務(wù)。

2. 發(fā)送自定義的廣播

2.1 發(fā)送標(biāo)準(zhǔn)廣播

具體思路

  1. 新建一個(gè)類(lèi),繼承自BroadcastReceiver,重寫(xiě)onReceive()方法
  2. 在配置文件中聲明廣播的名稱(chēng)等屬性
<receiver
android:name=".MyBroadcastReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
    <action android:name="com.example.broadcasttest.MY_BROADCAST"/>
</intent-filter>

</receiver>

3.發(fā)送廣播,通過(guò)獲得Intent實(shí)例,調(diào)用sendBroadcast()方法發(fā)送廣播。

Intent intent = new Intent("com.example.broadcasttest.MY_BROADCAST");
sendBroadcast(intent);

2.2發(fā)送有序廣播

  1. 發(fā)送有序廣播只需將3.中的sendBroadcast()改為sendOrderedBroadcast()即可。
  2. 在配置文件中可以通過(guò)android:priority屬性設(shè)置廣播接收的優(yōu)先級(jí)
<receiver
android:name=".MyBroadcastReceiver"
android:enabled="true"
android:exported="true">
<intent-filter android:priority="100">
        <action android:name="com.example.broadcasttest.MY_BROADCAST"/>
</intent-filter>

</receiver>

3.在某個(gè)廣播器中可以通過(guò)調(diào)用absortBroadcast()截?cái)嗤ㄖ^續(xù)傳播。

使用本地廣播

  • 使用本地廣播的注意點(diǎn)
  1. 本地廣播機(jī)制發(fā)出的廣播只能夠在應(yīng)用程序的內(nèi)部進(jìn)行傳遞,簡(jiǎn)單的解決了廣播的安全性問(wèn)題。并且廣播接收器也只能接收來(lái)自本應(yīng)用程序發(fā)出的廣播。
  2. 本地廣播主要就是使用LocalBroadcastManager來(lái)對(duì)廣播進(jìn)行管理,并提供了發(fā)送和注冊(cè)廣播接收器的方法。
  3. 本地廣播無(wú)法通過(guò)靜態(tài)注冊(cè)的方式來(lái)接收。因?yàn)殪o態(tài)注冊(cè)主要是為了讓程序在為啟動(dòng)的情況下也能收到廣播,而發(fā)送本地廣播的前提是程序處于啟動(dòng)狀態(tài)。
  • 使用本地廣播的優(yōu)勢(shì)

1.可以明確的知道發(fā)送的廣播不會(huì)離開(kāi)程序,因此不必?fù)?dān)心機(jī)密數(shù)據(jù)泄漏的問(wèn)題。

  1. 其他程序無(wú)法將廣播發(fā)送到我們的程序內(nèi)部,因此不必?fù)?dān)心安全漏洞隱患。
  2. 發(fā)送本地廣播比發(fā)送系統(tǒng)全局廣播更加高效。
  • 使用實(shí)例如下

    public class MainActivity extends AppCompatActivity {
    
      private IntentFilter intentFilter;
    
      private LocalReceiver localReceiver;
    
      private LocalBroadcastManager localBroadcastManager;
    
      @Override
      protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_main);
    
          localBroadcastManager = LocalBroadcastManager.getInstance(this);
          Button button = (Button) findViewById(R.id.button);
          button.setOnClickListener(new View.OnClickListener() {
              @Override
              public void onClick(View v) {
                  Intent intent = new Intent("com.example.broadcasttest.LOCAL_BROADCAST");
                  localBroadcastManager.sendBroadcast(intent);
              }
          });
          intentFilter = new IntentFilter();
          intentFilter.addAction("com.example.broadcasttest.LOCAL_BROADCAST");
          localReceiver = new LocalReceiver();
          //注冊(cè)廣播
          localBroadcastManager.registerReceiver(localReceiver, intentFilter);
      }
    
      //定義一個(gè)廣播接收器
      class LocalReceiver extends BroadcastReceiver {
          @Override
          public void onReceive(Context context, Intent intent) {
              Toast.makeText(context, "發(fā)送本地廣播", Toast.LENGTH_SHORT).show();
          }
      }
    

}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容