Android 本地廣播與全域性廣播
1. 全域性廣播和本地廣播的區別
全域性廣播:發出去的廣播可以被任何應用程式接收到
本地廣播:發出去的廣播只能被本應用程式接收到,一般使用LocalBroadcastManager對廣播進行管理。
2.註冊廣播
註冊廣播的方式一般有兩種:
- 在程式碼註冊(動態註冊)
- 在AndroidManifest.xml中註冊(靜態註冊)
動態註冊廣播監聽
新建一個類,讓它繼承自BroadcastReceiver並重寫父類的onReceive()方法就行了。當廣播到來時,onReceive()方法會得到執行,開發者就可以在這個方法中進行處理相應的邏輯。
//動態註冊廣播
IntentFilter myIntentFilter = new IntentFilter();
myIntentFilter.addAction(Constant.ACTION_NAME);
registerReceiver(new MyReceiver(), myIntentFilter);
public class MyReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
//相應邏輯處理
}
}
靜態註冊廣播監聽
動態註冊廣播缺點:動態註冊的廣播接收器可以自由的控制註冊於登出,在靈活性方面有很大的優勢,但是它也存在一個缺點,即必須要在程式啟動之後才能接收廣播。
靜態註冊就可以很好的彌補這個缺點,想要使用靜態註冊必須滿足兩點:
靜態註冊同樣是要新建一個類繼承BroadcastReceiver並重寫onReceive()方法
,還需要在AndroidManifest.xml中將這個廣播接收器的類名註冊進去
。
public class MyReceiver extends BroadcastReceiver {
@Override
public void onReceive (Context context, Intent intent) {
//相應邏輯處理
}
}
AndroidManifest.xml
<receiver android:name=".MyReceiver"/>
2.廣播接收器
Android中廣播接收器主要可分兩種型別:
標準廣播
標準廣播是一種完全非同步執行的廣播,在廣播發出去之後,所有的廣播接收
器幾乎都會在同一時刻接收到這條訊息,因此它們之間無任何先後順序可言。這種廣播的效率會比較高,但同時也意味著它是無法被截斷的。有序廣播
有序廣播則是一種同步執行的廣播,在廣播發出去之後,同一時刻只會有一個廣播接收器能夠收到這條訊息,當這個廣播接收器中的邏輯執行完畢後,廣播才會繼續傳遞。所以此時的廣播接收器是有先後順序的,優先順序高的廣播接收器就可以先接收到廣播訊息,並且前面的廣播接收器還可以截斷正在傳遞的關公,這樣的廣播接收器就無法接收到訊息了。
傳送標準廣播
1.先定義一個廣播接收器來準備接受此廣播
public static class MyBroadcast extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "接收到了自定義廣播", Toast.LENGTH_SHORT).show();
}
}
2.在AndroidManifest.xml中註冊這個廣播接收器
<receiver android:name=".MyBroadcast">
<intent-filter>
<action android:name="com.example.mybroadcast" />
</intent-filter>
</receiver>
3.傳送一個廣播
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent("com.example.mybroadcast");
sendBroadcast(intent);
}
});
傳送有序廣播
為了直觀的研究有序廣播,我又新建了一個專案。這個專案的內容和之前的一樣
(廣播接收器名為 MyBroadcast_B
)
傳送有序廣播只需要改動一行程式碼,即將sendBroadcast()方法改成sendOrderedBroadcast()方法。sendOrderedBroadcast()方法接收兩個引數,第一個仍是Intent,第二個引數是與許可權相關的字串,這裡傳入null就行了
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent("com.example.mybroadcast");
sendOrderedBroadcast(intent, null);
}
});
通過android:priority屬性給廣播接收器設定優先順序,從而設定廣播接收器的先後順序,優先順序比較高的接收器就可以先收到廣播。
<receiver android:name=".MyBroadcast_B">
<intent-filter android:priority="100">
<action android:name="com.example.mybroadcast" />
</intent-filter>
</receiver>
既然已經獲得了優先權,那麼我就可以讓MyBroadcastReceive選擇是否允許廣播繼續傳遞了,可以在onReceive()
方法中新增abortBroadcast()
方法,用來截斷廣播。
public static class MyBroadcast_B extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "接收到了自定義廣播", Toast.LENGTH_SHORT).show();
/*當MyBroadcast_B 接收到訊息後 並截斷。
*此時MyBroadcast將不會再接收到廣播
*/
abortBroadcast();
}
}
全域性廣播安全性
為了提高全域性廣播的安全性,一般會增加許可權等控制
<permission android:name="com.example.mybroadcast"/>
<receiver android:name=".MyBroadcast_B"
android:exported="true"
android:permission="com.example.mybroadcast">
<intent-filter>
<action android:name="com.example.mybroadcast" />
</intent-filter>
</receiver>
3.本地廣播
之前所講的傳送和接收廣播都是屬於系統全域性廣播,也就是說發出的廣播可以被其他任何應用程式接收到,這樣大大降低了安全性。因此Android中引入了一套本地廣播機制,使用這個機制發出的廣播只能夠在應用程式的內部進行傳遞,並且廣播接收器也只接收來自本地應該程式發出的廣播,大大的解決了廣播的安全性問題。用法並不複雜,主要就是使用了一個LocalBroadcastManager來對廣播進行管理,並提供了傳送廣播和註冊廣播接收器的方法
public class LocalBroadcastMngActivity extends AppCompatActivity {
private IntentFilter intentFilter;
private LocalReceiver localReceiver;
private LocalBroadcastManager localBroadcastManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_local_broadcast_mng);
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.mybroadcast");
localBroadcastManager.sendBroadcast(intent);//傳送本地廣播
}
});
intentFilter = new IntentFilter();
intentFilter.addAction("com.example.mybroadcast");
localReceiver = new LocalReceiver();
//註冊本地廣播監聽器
localBroadcastManager.registerReceiver(localReceiver, intentFilter);
}
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(localReceiver);//取消註冊
}
}
class LocalReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(LocalBroadcastMngActivity.this, "接收到本地廣播", Toast.LENGTH_SHORT).show();
}
}
地廣播的用法和之前動態註冊廣播的用法大致相同,只不過現在首先是通過LocalBroadcastManager
的getInstance()
方法得到了它的一個例項;然後再註冊廣播接收器的時候呼叫的是LocalBraodcastManager
的sendBroadcast()
方法,僅此而已。
另外一點還需要說明,本地廣播是無法通過靜態註冊的方式來接收的。
本地廣播的優點
可以明確的知道正在傳送的廣播不會離開我們的程式,因此不需要擔心機密資料洩露問題。
其他的程式無法將廣播發送到我們程式的內部,因此不需要擔心會有安全漏洞的隱患。
傳送本地廣播比起傳送系統全域性廣播將會更加高效。