android學習筆記之四:四大元件之BroadcastReceiver
1.定義廣播接收者
- 定義一個類繼承BroadcastReceiver,並重寫onReceive()方法。
@Override
public class SMSBroadCastReceiver extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
}
}
- 在清單檔案中配置該類(靜態註冊),指定接收的廣播種類
<receiver android:name="com.example.broadcast.SMSBroadCastReceiver" >
<intent-filter >
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
廣播是通過intent傳送的,intent中會攜帶一個action,系統會在所有清單檔案中尋找,看哪一個廣播接收者的intent-filter和廣播中的intent是匹配的,那麼這個廣播接收者就會收到這條廣播,它的onReceive方法就會執行。
BroadcastReceiver除了在清單檔案中宣告,也可以在程式碼中宣告,使用registerReceiver方法動態註冊Receiver
動態註冊時,無須在AndroidManifest中註冊receiver元件。直接在程式碼中通過呼叫Context的registerReceiver函式,可以在程式中動態註冊BroadcastReceiver。registerReceiver的定義形式如下:
SMSBroadcastReceiver receiver = new SMSBroadcastReceiver();
IntentFilter intentFilter= new IntentFilter();
intentFilter.addAction("android.provider.Telephony.SMS_RECEIVED" );
registerReceiver(receiver, intentFilter);
動態註冊的廣播接收者,還需要在onDestroy()回撥中取消註冊
unregisterReceiver(receiver)。
2.傳送自定義廣播
- 建立自定義廣播:
//建立一個傳遞訊息的意圖物件
Intent intent = new Intent();
//設定要廣播的事件型別
intent.setAction("com.example.broadcast.appointment");
//設定廣播的訊息資料
intent.putExtra("appointment", "明天天氣晴朗,是約會的好日子......");
//傳送一個廣播訊息
sendBroadcast(intent);
- 接收自定義廣播:
public class MyBroadcastReceiver extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
String appointment = intent.getStringExtra("appointment");
Toast.makeText(context, appointment , 1).show();
}
}
在AndroidManifest.xml中配置廣播接收者:
<receiver android:name="com.example.broadcast.MyBroadcastReceiver">
<intent-filter>
<action android:name="com.example.broadcast.appointment">
</intent-filter>
</receiver>
3.廣播的兩種型別
無序廣播:所有跟廣播的intent匹配的廣播接收者都可以收到該廣播,並且是沒有先後順序(同時收到)
- 接收者不能將處理結果傳遞給下一個接收者,並且無法終止廣播Intent的傳播。
- Context.sendBroadcast(intent);
有序廣播:所有跟廣播的intent匹配的廣播接收者都可以收到該廣播,但是會按照廣播接收者的優先順序來決定接收的先後順序,優先順序高的先收到,優先順序低的後收到。
- 優先級別宣告在 intent-filter 元素的 android:priority 屬性中,取值範圍:-1000~1000,優先級別也可以呼叫IntentFilter物件的setPriority()進行設定 。
- Context.sendOrderedBroadcast(intent);
- 結果接收者:所有廣播接收者都接收到廣播之後,它才接收,並且一定會接收
- abortBroadCast():阻止其他接收者接收這條廣播,類似攔截,只有有序廣播可以被攔截
4.使用本地廣播
只在應用程式內部進行傳遞的廣播,傳送和接收都只在本應用程式有效。
本地廣播是無法通過靜態註冊來實現的。因為靜態註冊是為了讓程式未啟動也能接收廣播。本地廣播是在本程式內進行
傳遞,肯定是已經啟動了,因此也完全不需要靜態註冊。使用LocalBroadcastManager對廣播進行管理,程式碼如下。
public class MainActivity extends Activity {
private IntentFilter intentFilter;
private LocalReceiver localReceiver;
//本地廣播資料型別例項
private LocalBroadcastManager localBroadcastManager;
@Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
supportRequestWindowFeature(Window.FEATURE_NO_TITLE);
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.broadcast.LOCAL_BROADCAST");
//傳送本地廣播。
localBroadcastManager.sendBroadcast(intent);
}
});
//新建intentFilter並給其action標籤賦值。
intentFilter = new IntentFilter();
intentFilter.addAction("com.example.broadcast.LOCAL_BROADCAST");
//建立廣播接收器例項,並註冊。將其接收器與action標籤進行繫結。
localReceiver = new LocalReceiver();
localBroadcastManager.registerReceiver(localReceiver,intentFilter);
}
//在onDestroy()方法中取消註冊
@Override
public void onDestroy(){
super.onDestroy();
//取消註冊呼叫的是unregisterReceiver()方法,並傳入接收器例項。
localBroadcastManager.unregisterReceiver(localReceiver);
}
class LocalReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context,Intent intent){
Toast.makeText(context,"這是本地廣播接收器",Toast.LENGTH_SHORT).show();
}
}
}
- 本地廣播的優勢
- 可以明確地知道正在傳送的廣播不會離開我們的程式, 因此不需要擔心機密資料洩漏的問題。
- 其他的程式無法將廣播發送到我們程式的內部, 因此不需要擔心會有安全漏洞的隱患。
- 傳送本地廣播比起傳送系統全域性廣播將會更加高效。
5.廣播的生命週期
廣播接收者的生命週期是非常短暫的,在接收到廣播的時候建立,onReceive()方法結束之後銷燬
廣播接收者中不要做一些耗時的工作,否則會彈出Application No Response錯誤對話方塊
最好也不要在廣播接收者中建立子執行緒做耗時的工作,因為廣播接收者被銷燬後進程就成為了空程序,很容易被系統殺掉
耗時的較長的工作最好放在服務中完成