簡介
Broadcast Receiver,即廣播接收器,顧名思義,通過廣播的方式進行消息傳遞。
分類
標準廣播
這是一種完全異步執(zhí)行的廣播,這種廣播發(fā)出后,所有接收器之間幾乎同時收到消息,它們之間沒有任何順序可言,因此這種廣播效率比較高,無法被攔截。有序廣播
這是一種同步執(zhí)行的廣播,這種廣播發(fā)出后,各接收器是按照注冊的優(yōu)先級的順序來進行接收的,優(yōu)先級高的先接收,優(yōu)先級低的后接收,并且可以被中斷,一旦被中斷則后續(xù)接收器則無法接收到此消息了。
使用方式
廣播使用方式基本相同,在BroadcastReceiver類中的onReceive()方法中處理接收器邏輯,但是不能進行耗時操作,因為在這里不允許開啟線程的;另外廣播是有優(yōu)先級的,優(yōu)先級高的先收到廣播。
- 標準廣播
-
系統(tǒng)廣播
- 靜態(tài)注冊
第一步,編寫廣播接收器處理代碼,該類繼承自BroadcastReceiver類
public class BootCompleteReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Toast.makeText(context, "Boot Complete", Toast.LENGTH_LONG).show(); } }第二步,在manifest文件中聲明
<receiver android:name=".broadcast.BootCompleteReceiver" 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" />靜態(tài)注冊的方式是通過xml在manifest文件中進行注冊,其特點是:在程序未啟動的情況也能接收到廣播消息,并且無法取消注冊。
- 動態(tài)注冊
第一步,編寫廣播接收器處理代碼,該類繼承自BroadcastReceiver類
public class NetworkChangeReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { //get the state of network ConnectivityManager connectivityManager = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo(); String state; if (networkInfo != null && networkInfo.isAvailable()) { state = "available"; } else { state = "unavailable"; } Toast.makeText(context, "Network is " + state, Toast.LENGTH_LONG).show(); } }第二步,在Activity 中注冊及取消
public class BroadcastDynamicSystemActivity extends AppCompatActivity { private IntentFilter intentFilter; private NetworkChangeReceiver networkChangeReceiver; public static void startAction(Context context) { context.startActivity(new Intent(context, BroadcastDynamicSystemActivity.class)); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_broadcast_dynamic_system); //register network change broadcast receiver this.intentFilter = new IntentFilter(); this.intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE"); this.networkChangeReceiver = new NetworkChangeReceiver(); registerReceiver(this.networkChangeReceiver, this.intentFilter); } @Override protected void onDestroy() { super.onDestroy(); //unregister network change broadcast receiver unregisterReceiver(this.networkChangeReceiver); } }第三步,在manifest文件中添加網(wǎng)絡訪問權限
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />動態(tài)注冊的流程是:先編寫廣播接收器的處理方法(繼承自BroadcastReceiver類),然后在應用的地方進行注冊和取消注冊。這種方式的特點是:
1. 只有動態(tài)注冊代碼執(zhí)行了才會接收廣播,沒執(zhí)行是不會收到廣播的;
2. 需要實時取消注冊,以防內(nèi)存泄漏。 -
自定義廣播
- 標準廣播
第一步,編寫廣播接收器處理代碼,該類繼承自BroadcastReceiver類
public class MyStandardBroadcastReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Toast.makeText(context, "My Standard Broadcast Receiver", Toast.LENGTH_LONG).show(); } }第二步,在manifest中注冊(此為靜態(tài)注冊方式注冊,亦可動態(tài)方式注冊)
<receiver android:name=".broadcast.MyStandardBroadcastReceiver"> <intent-filter> <action android:name="com.example.broadcast.MY_BROADCAST" /> </intent-filter> </receiver>第三步,發(fā)送自定義廣播
sendBroadcast(new Intent("com.example.broadcast.MY_BROADCAST"));這里需要注意的是廣播的action name必須一致。
- 有序廣播
第一步,編寫廣播接收器處理代碼,該類繼承自BroadcastReceiver類
public class MyOrderedBroadcastReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Toast.makeText(context, "My Ordered Broadcast Receiver", Toast.LENGTH_LONG).show(); //中斷傳播 abortBroadcast(); } }第二步,在manifest中注冊(此為靜態(tài)方式注冊,亦可動態(tài)注冊)
<receiver android:name=".broadcast.MyOrderedBroadcastReceiver"> <intent-filter android:priority="100"> <action android:name="com.example.broadcast.MY_BROADCAST" /> </intent-filter> </receiver>第三步,發(fā)送自定義廣播
sendOrderedBroadcast(new Intent("com.example.broadcast.MY_BROADCAST"), null);有序廣播和標準廣播使用方式上唯一區(qū)別在于發(fā)送方法不同以及有序廣播可以通過
abortBroadcast()方法來中斷廣播的傳遞。
-
-
本地廣播
標準廣播都是全局的,即不僅本應用會接收而且其他應用也可以接收,因此如果一直發(fā)送標準廣播不僅會對系統(tǒng)造成污染,而且也會帶來安全隱患,為了解決這些問題,Android系統(tǒng)引入了本地廣播機制。
-
使用方法
第一步,編寫廣播接收器處理代碼,該類繼承自BroadcastReceiver類public class LocalBroadcastReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Toast.makeText(context, "Local Broadcast Receiver", Toast.LENGTH_LONG).show(); } }第二步,發(fā)送廣播
private IntentFilter intentFilter; private LocalBroadcastReceiver localBroadcastReceiver; private LocalBroadcastManager localBroadcastManager; @Override protected void onCreate(Bundle savedInstanceState) { …… this.intentFilter = new IntentFilter(); this.intentFilter.addAction("com.example.broadcast.MY_LOCAL_BROADCAST"); this.localBroadcastManager = LocalBroadcastManager.getInstance(this); this.localBroadcastReceiver = new LocalBroadcastReceiver(); this.localBroadcastManager.registerReceiver(this.localBroadcastReceiver, this.intentFilter); } @Override protected void onDestroy() { super.onDestroy(); this.localBroadcastManager.unregisterReceiver(this.localBroadcastReceiver); } //發(fā)送本地廣播 this.localBroadcastManager.sendBroadcast(new Intent("com.example.broadcast.MY_LOCAL_BROADCAST")); -
特點
- 消息只在本應用內(nèi)進行傳遞;
- 無法通過靜態(tài)注冊的方式進行注冊;
- 比系統(tǒng)全局廣播更高效。
-
總結
- 當需要在程序未啟動就接收廣播消息時,使用靜態(tài)注冊方式注冊廣播;
- 當需要靈活控制接收或者不接受廣播消息時,使用動態(tài)注冊方式注冊廣播;
- 當廣播消息僅在本應用內(nèi)部進行傳遞,使用本地廣播更高效更安全;
- 當需要對廣播消息對傳遞進行順序控制時,使用有序廣播廣播。