Android筆記三十三.BroadcastReceiver使用,broadcastreceiver
廣播是一種廣泛運用在應用程式之間傳輸資訊的機制,而BroadcastReceiver是對發送出來的廣播進行過濾接收並響應的一類組件。BroadcastReceiver本質上是一種全域監聽器,用於監聽系統全域的廣播訊息並接收指定的廣播,因此它可以非常方便地實現系統中不同組件之間的通訊。如下為BroadcastReceiver知識點結構:一、發送與接收廣播1.發送廣播 廣播的發送通過調用Context.sendBroadcast()、Context.sendOderedBroadcast()來實現: (1)Context.sendBroadcast(Intent intent):用於發送普通廣播,其中intent參數表示接收該廣播的廣播接收者所需要滿足的條件,以及廣播所傳遞的資料; (2)Context.sendOderedBroadcast(Intent intent, String receiverPermission):用於發送有序廣播,intent參數同上,receiverPermission表示接收該廣播的許可許可權。2.接收廣播 廣播的接收,則利用組件BroadcastReceiver是對發送出來的廣播進行過濾接收並響應指定的廣播。通常一個廣播可以被訂閱了該Intnet的多個廣播接收者所接收,如同一個廣播台,可以被多個多位聽眾收聽一樣。啟動BroadcastReceiver步驟:(1)建立Intent,指定BroadcastReceiver的特徵;(2)調用Context的sendBroadcast()(發送普通廣播)或sendOrderBroadcast()(發送有序廣播)方法來發送廣播,觸發指定的BroadcasttReceiver。 為此,當應用程式發出一個廣播之後,所有匹配該Intent的BroadcastReceiver都有可能被啟動。二、廣播的分類1.普通廣播 是完全非同步,可以在同一時刻(邏輯上)被所有接收者接收到,訊息傳遞的效率比較高。但缺點是接收者不能將處理結果傳遞給下一個接收者,並且無法終止Broadcast Intent的傳播。2.有序廣播 該廣播的接收者將按預先聲明的優先順序次序接收廣播。有序廣播接收者可以終止廣播的傳播(通過調用abortBroadcast()方法),廣播的傳播一旦終止,後面的接收者就無法接收到廣播。另外,廣播的接收者可以將資料傳遞給下一個接收者(通過setResultExtras(Bundle bundle)方法)。三、BroadcastReceiver應用開發步驟 BroadcastReceiver自身並不實現圖形化使用者介面,但是當它收到某個訊息之後,可以啟動Activity作為響應,或者通過NotificationManager提醒使用者,或者啟動Service等等。1.建立廣播接收器。實現一個繼承於BroadcastReceiver基類的子類,並實現裡面的onReceiver()方法;
- public class MyBroadcastReceiver extends BroadcastReceiver
- {
- public void onReceiver(Context context,Intent intent){
- }
- }
在onReceiver()方法中,接收了一個Intent的參數,通過它可以擷取廣播所攜帶的資料,也可以啟動一個Service服務來處理耗時任務等。
2.發送廣播,並指定該廣播的Intent屬性 廣播接收者註冊好了以後,並不會直接運行,必須在接收廣播之後才會被調用。因此,必須首先發送廣播,在Activity或Service調用Context的sendBroadcast(Intent intent)或sendOrderedBroadcast(Intent intent, String receiverPermission)發送廣播。
3.註冊廣播接收器,指定其接收哪一個廣播。 建立完廣播接收者後,並不能馬上使用,還必須為它(廣播接收者)註冊一個指定的廣播,就如同我們有了收音機後,還必須選擇收聽哪個頻道一樣。(1)靜態註冊:是指在AndroidManifest.xml檔案中進行註冊。
- <receiver android:name=".MyBroadcastReceiver">
- <intent-filter>
- <action
- android:name = "com.jiangdongguo.android.myBroadcastReceover">
- <action/>
- </intent-filter>
- </receiver>
(2)動態註冊:需要在代碼中動態指定廣播位址並註冊,通常是在Activity或Service中調用ContextWrapper的
- registerReceiver(BroadcastReceiver receiver,IntentFilter filter)方法進行註冊。
- MyBroadcastReceiver myBroadcastReceiver = new MyBroadcastReceiver();
- IntentFilter filter = new IntentFilter("com.jiangdongguo.android.myBroadcastReceover"); //指定接收哪個廣播
- registerReceiver(myBroadcastReceiver);
其中,MyBroadcastReceiver為基類BroadcastReceiver子類。註冊完成後,即可接收相應的廣播訊息,一旦廣播(Broadcast)事件發生後,系統就會建立對應的BroadcastRecevier執行個體,並自動觸發它的onReceiver()方法,onReceiver()方法執行後,BroadcastReceiver的執行個體就會被銷毀。
三、源碼實戰實現:在Activity中啟動一個廣播,通過廣播接收器接收該廣播並作出響應。
1.MyBroadcastReceiver.java: 繼承於BroadcastReceiver子類-廣播接收器,用於接收指定廣播並作出相應響應。
- package com.example.mybroadcast;
- import android.content.BroadcastReceiver;
- import android.content.Context;
- import android.content.Intent;
- import android.widget.Toast;
- /*BroadcastReceiver子類
- * 用於接收指定發送廣播*/
- public class MyBroadcastReceiver extends BroadcastReceiver {
- @Override
- public void onReceive(Context arg0, Intent arg1) {
- Toast.makeText(arg0, "我是BroadcastReceiver,我已經接收到發送的廣播!", Toast.LENGTH_SHORT).show();
- }
- }
注釋:我們可以在onReceiver()方法中擷取Intent攜帶的資料,也可以啟動一個Service服務來執行耗時任務等。
2.MainActivity.java 主Activity,用於發送一個廣播,或者可以代替AdroidManifest.xml工程檔案註冊廣播接收器
- package com.example.mybroadcast;
- import android.app.Activity;
- import android.content.Intent;
- import android.content.IntentFilter;
- import android.os.Bundle;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- public class MainActivity extends Activity {
- private Button sendBroad;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- /*1.廣播接收器註冊方式二:註冊一個廣播接收器*/
- MyBroadcastReceiver myBroadcastReceiver = new MyBroadcastReceiver();
- IntentFilter filter = new IntentFilter("com.jiangdongguo.Android.BroadcastReceiver");
- registerReceiver(myBroadcastReceiver,filter);
-
- sendBroad = (Button)findViewById(R.id.send);
- sendBroad.setOnClickListener(new OnClickListener(){
- public void onClick(View v) {
- /*2.發送一個廣播,並指明其action屬性*/
- //a.指明該廣播的action屬性
- Intent intent = new Intent("com.jiangdongguo.Android.BroadcastReceiver");
- //b.發送廣播
- sendBroadcast(intent);
- }
- });
-
- }
- }
3.AndroidManifest.xml 工程檔案,在這裡的作用是增加對BroadcastReceiver註冊。
- <?xml version="1.0" encoding="utf-8"?>
- <manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.example.mybroadcast"
- android:versionCode="1"
- android:versionName="1.0" >
- <uses-sdk
- android:minSdkVersion="8"
- android:targetSdkVersion="14" />
- <application
- android:allowBackup="true"
- android:icon="@drawable/ic_launcher"
- android:label="@string/app_name"
- android:theme="@style/AppTheme" >
- <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>
- <!--廣播接收器註冊方式一: 接收的哪一個廣播-->
- <!-- <receiver android:name=".MyBroadcastReceiver">
- <intent-filter >
- <action android:name="com.jiangdongguo.Android.BroadcastReceiver"/>
- </intent-filter>
- </receiver> -->
- </application>
- </manifest>
效果示範:源碼分析:(1)如果確定需要根據廣播來完成一項比較耗時的操作,則可以考慮通過Intent啟動一個Service來完成操作。不應考慮使用新線程去完成耗時的操作,因為BroadcastReceiver本身的生命週期極短,可能出現的情況是子線程可能沒有結束,BroadcastReceiver就已經退出了。(2)如果廣播接收者所在的進程結束了,雖然該進程內還有使用者啟動的新線程,但由於該進程內不包含任何活動組件,因此系統可能在記憶體緊張時優先結束線程。這樣就可能導致BroadcastReceiver啟動的子線程不能執行完成。