Android開發22——廣播接收者BroadcastReceiver的原理和注冊方式
一、廣播機製的基本概念
當某個事件產生時(如一條短信發來或一個電話打來),android操作係統會把這個事件廣播給所有注冊的廣播接收者,需要處理這個事件的廣播接收者進行處理。其實這就是日常生活中的廣播。發生一個新聞後,廣播電台會廣播這個新聞給打開收音機的人,對這個新聞感興趣的人會關注,可能會拿筆記下。新聞就是事件,廣播電台就是android係統,打開收音機的人就是廣播接收者,感興趣的人就是需要處理該事件的廣播接收者,拿筆記下就是對該事件進行的操作。
二、廣播的分類——普通廣播和有序廣播
①普通廣播:完全異步,邏輯上可以被任何廣播接收者接收到。優點是效率較高。缺點是一個接收者不能將處理結果傳遞給下一個接收者,並無法終止廣播intent的傳播。
②有序廣播:按照被接收者的優先級順序,在被接收者中一次傳播。比如有三個廣播接收者A,B,C,優先級是A > B > C。那這個消息先傳給A,再傳給B,最後傳給C。每個接收者有權中終止廣播,比如B終止廣播,C就無法接收到。此外A接收到廣播後可以對結果對象進行操作,當廣播傳給B時,B可以從結果對象中取得A存入的數據。如係統收到短信發出的廣播就是有序廣播。
三、注冊廣播接收者的兩種方式
①在AndroidManifest.xml中注冊
在配置文件中注冊的接收者的特點是即使應用程序已被關閉,該接收者依然可接受它感興趣的廣播,比如手機電池電量的廣播接收者,沒有必要將某個程序開啟。下麵的例子1、2廣播接收者會接收到撥打電話的廣播。
<application android:icon="@drawable/icon" android:label="@string/app_name"> <activity android:name=".MainActivity" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <!-- 廣播接收者1--> <receiver android:name=".BroadcastReceiver1"> <intent-filter> <action android:name="android.intent.action.CALL"></action> </intent-filter> </receiver> <!-- 廣播接收者2 --> <receiver android:name=".BroadcastReceiver2"> <intent-filter> <action android:name="android.intent.action.CALL"></action> </intent-filter> </receiver> <!-- 廣播接收者3 --> <receiver android:name=".BroadcastReceiver3"> <intent-filter> <action android:name="android.intent.action.PICK"></action> </intent-filter> </receiver> </application>
/** * 模擬撥打電話廣播 * * @author 徐越 * */ public class MainActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); Intent intent = new Intent(); intent.setAction("android.intent.action.CALL"); this.sendBroadcast(intent); } } /** * 每次接收廣播都會生成新的BroadcastReceiver1,當處理完onReceive方法後就不會再被使用 * 再次接收就在生成新的BroadcastReceiver1對象 * * @author 徐越 * */ public class BroadcastReceiver1 extends android.content.BroadcastReceiver { public BroadcastReceiver1() { Log.i("xy_Receiver", "construtor1"); } @Override public void onReceive(Context context, Intent intent) { Log.i("xy_Receiver", "onReceive1"); } } /** * 廣播接收者2 * * @author 徐越 * */ public class BroadcastReceiver2 extends android.content.BroadcastReceiver { public BroadcastReceiver2() { Log.i("xy_Receiver", "construtor2"); } @Override public void onReceive(Context context, Intent intent) { Log.i("xy_Receiver", "onReceive2"); } } /** * 廣播接收者3 * * @author 徐越 * */ public class BroadcastReceiver3 extends android.content.BroadcastReceiver { public BroadcastReceiver3() { Log.i("xy_Receiver", "construtor3"); } @Override public void onReceive(Context context, Intent intent) { Log.i("xy_Receiver", "onReceive3"); } }
②在Activity中注冊
在Activity中綁定接收者必須依附該應用程序存在,或者一個BroadcastReceiver用於更新UI,就沒有必要再程序關閉時接收者還運行,故無需在AndroidManifest.xml中注冊而可以放在Activity中注冊。
/** * Activity中注冊廣播接收者 * * @author 徐越 * */ public class MainActivity extends Activity { private BroadcastReceiver receiver; private static final String CALL_ACTION = "android.intent.action.CALL"; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } /** * 模擬發送一個電話的廣播 * * @param v */ public void sendBroadCast(View v) { Intent intent = new Intent(); intent.setAction("android.intent.action.CALL"); this.sendBroadcast(intent); } public void bindReceiver(View v) { receiver = new BroadcastReceiver(); IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(CALL_ACTION); this.registerReceiver(receiver, intentFilter); } public void unBindReceiver(View v) { this.unregisterReceiver(receiver); } } public class BroadcastReceiver extends android.content.BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Log.i("xy", "receiver"); } }
最後更新:2017-04-04 07:03:09