FC 5 廣播機制
阿新 • • 發佈:2018-12-22
廣播的註冊方式:
- 動態註冊
- 靜態註冊
廣播的傳送方式:
- 普通廣播
- 有序廣播
- 本地廣播
特殊說明
- 不要在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例項,, * 添加了android.net.conn.CONNECTIVITY_CHANGE的action,當系統發出這個廣播時,我們就能收到 * 建立了NetworkchangeReceiver例項, * 呼叫registerReceiver對廣播進行動態註冊 */ intentFilter = new IntentFilter(); intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE"); networkchangeReceiver = new NetworkchangeReceiver(); registerReceiver(networkchangeReceiver, intentFilter); } @Override protected void onDestroy() { super.onDestroy(); //動態註冊的廣播必須取消註冊。在onDestroy呼叫unregisterReceiver方法 unregisterReceiver(networkchangeReceiver); } /** * 定義內部類,NetworkchangeReceiver, * 繼承BroadcastReceiver,重寫父類的onReceive方法 * 每當網路狀態發生變化時,就會執行,這裡簡單toast。 */ private class NetworkchangeReceiver extends BroadcastReceiver { public void onReceive(Context context, Intent intent) { Toast.makeText(context, "network changes", Toast.LENGTH_SHORT).show(); } } }
//靜態註冊 //1、new other broadcast Receiver,建立廣播器MyReceiver,重寫onReceive方法 //2、在配置檔案中新增<intent-filter> //3、新增網路許可權 <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> public class MyReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Toast.makeText(context, "network changes", Toast.LENGTH_SHORT).show(); } } //AndroidManifest的配置檔案裡 <receiver android:name=".MyReceiver" android:enabled="true" android:exported="true"> <intent-filter> <action android:name="android.net.conn.CONNECTIVITY_CHANGE"/> </intent-filter> </receiver>
關於普通廣播
也就是標準廣播,普通廣播是一種完全非同步執行的廣播,在廣播發出之後,所有的廣播接收器幾乎都會在同一時刻接收到這條廣播訊息,因此它們接收的先後是隨機的。另外,接收器不能截斷普通廣播。
- 建立廣播接收器
- AndroidManifest進行靜態註冊,新增對應的許可權
- 介面新增按鈕,mainactivity裡對按鈕新增單擊事件,傳送廣播。
public class MyReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Toast.makeText(context, "received BroadcastReceiver", Toast.LENGTH_SHORT).show(); } }
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<receiver
android:name=".MyReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
public void onclick(View view) {
Intent intent = new Intent("firstcode.zs.com.fc_5.MyReceiver");
sendBroadcast(intent);
}
關於有序廣播
它是一種同步執行的廣播,在廣播發出之後,同一時刻只會有一個廣播接收器能夠收到這條廣播訊息,當這個廣播接收器中的邏輯執行完畢後,廣播才會繼續傳遞,所以此時的廣播接收器是有先後順序的,且優先順序(priority)高的廣播接收器會先收到廣播訊息。有序廣播可以被接收器截斷使得後面的接收器無法收到它。
- 傳送一個有序廣播和普通廣播的方法有細微的區別,只需要將sendBroadcast()方法改成sendOrderedBroadcast()方法, 它接收兩個引數,第一個引數仍是Intent,第二個引數是一個與許可權相關的字串,這裡傳入 null就行。
- 只要在註冊的時候設定它的優先順序android:priority為100,數值越大優先順序就越高,現在就能保證它一定會在MyReceiver之前收到廣播。
- 如果在AnotherReceiver的onReceive()方法中呼叫了abortBroadcast()方法,表示將這條廣播截斷,後面的廣播接收器將無法再接收到這條廣播。現在重新執行程式,並點選一下按鈕,然後會發現,只有AnotherReceiver中的Toast資訊彈出,說明這條廣播經過AnotherReceiver之後確實是終止傳遞了。
關於本地廣播
使用本地廣播,自己在之前用過,參考這篇文章
前面學到的的廣播都屬於系統全域性廣播,即發出的廣播可被其他應用程式接收到,且我們也可接收到其他任何應用程式傳送的廣播。為了能夠簡單地解決全域性廣播可能帶來的安全性問題,Android引入了一套本地廣播機制,使用這個機制發出的廣播只能夠在應用程式的內部進行傳遞,並且廣播接收器也只能接收本應用程式發出的廣播。
實現本地廣播的傳送和接收也很簡單,主要使用了一個LocalBroadcastManager來對廣播進行管理,並提供了相應的傳送廣播和註冊廣播接收器的方法。
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("firstcode.zs.com.fc_5.LOCAL_BROADCAST");
localBroadcastManager.sendBroadcast(intent); // 傳送本地廣播
}
});
intentFilter = new IntentFilter();
intentFilter.addAction("firstcode.zs.com.fc_5.LOCAL_BROADCAST");
localReceiver = new LocalReceiver();
localBroadcastManager.registerReceiver(localReceiver, intentFilter); // 註冊本地廣播監聽器
}
@Override
protected void onDestroy() {
super.onDestroy();
localBroadcastManager.unregisterReceiver(localReceiver);
}
class LocalReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "received local broadcast", Toast.LENGTH_SHORT).show();
}
}
}
關於不要在onreceive中新增過多的邏輯或超時操作:
廣播接收器不允許開啟執行緒。當onreceive方法運行了較長時間沒有結束時,程式就會報錯。
關於本地廣播無法通過靜態註冊方式來接收
靜態註冊主要是為了讓程式在未啟動的情況下也能收到廣播,而傳送本地廣播是我們的程式肯定已經啟動了,完全不需要靜態註冊。
FC系列文章,均參考郭神的《第一行程式碼》,所以這裡的文章均為轉載