標籤:broadcastreceiver 啟動broadcastreceiver的 如何建立broadcastreceive broadcastreceiver的生命 broadcastreceiver的使用
BroadcastReceiver,顧名思義就是“廣播接收者”的意思,它是Android四大基本組件之一,這種組件本質上是一種全域的監聽器,用於監聽系統全域的廣播訊息。它可以接收來自系統和應用的的廣播。
由於BroadcastReceiver是一種全域的監聽器,因此它可以非常方便地實現系統不同組件之間的通訊。比如Activity與通過startService()方法啟動的Service之間通訊,就可以藉助於BroadcastReceiver來實現。
BroadcastReceiver簡介:
BroadcastReceiver用於接收程式(包括系統程式和一般應用)通過sendBroadcast()方法發出的Broadcast intents。
程式啟動BroadcastReceiver的步驟(發出廣播):
1) 建立需要啟動BroadcastReceiver的Intent。
2) 調用Context的sendBroadcast()或sendOrderedBroadcast()方法來啟動指定的BroadcastReceiver。其中sendBroadcast發送的是普通廣播,sendOrderedBroadcast發送的是有序廣播。
當應用發出一個Broadcast Intent之後所匹配該Intent的組件都可能被啟動。
建立BroadcastReceiver的步驟:
第一步:建立BroadcastReceiver的子類:
由於BroadcastReceiver本質上是一種監聽器,所以建立BroadcastReceiver的方法也非常簡單,只需要建立一個BroadcastReceiver的子類然後重寫onReceive(Context context, Intentintent)方法即可。
具體代碼如下:
public class MyBroadcastReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { // TODO Auto-generated method stub String msg=intent.getExtras().get("msg").toString(); Toast.makeText(context,"intent.getAction()"+intent.getAction().toString(), Toast.LENGTH_LONG).show(); System.out.println("msg:"+msg); }}
第二步:註冊BroadcastReceiver
一旦實現了BroadcastReceiver,接下就應該指定該BroadcastReceiver能匹配的Intent即註冊BroadcastReceiver。註冊BroadcastReceiver的方式有兩種:
第一種是靜態註冊:這種方法是在配置AndroidManifest.xml設定檔中註冊,通過這種方式註冊的廣播為常駐型廣播,也就是說如果應用程式關閉了,有相應事件觸發,程式還是會被系統自動調用運行。例如:
<!-- 在設定檔中註冊BroadcastReceiver能夠匹配的Intent --><receiver android:name="com.example.test.MyBroadcastReceiver"> <intent-filter> <action android:name="android.intent.action.MyBroadcastReceiver"></action> <category android:name="android.intent.category.DEFAULT"></category> </intent-filter></receiver>
第二種是動態註冊:這種方法是通過代碼在.Java檔案中進行註冊。通過這種方式註冊的廣播為非常駐型廣播,即它會跟隨Activity的生命週期,所以在Activity結束前我們需要調用unregisterReceiver(receiver)方法移除它。例如:
//通過代碼的方式動態註冊MyBroadcastReceiverMyBroadcastReceiver receiver=new MyBroadcastReceiver();IntentFilter filter=new IntentFilter();filter.addAction("android.intent.action.MyBroadcastReceiver");//註冊receiverregisterReceiver(receiver, filter);
注意:如果我們在Activity中註冊了BroadcastReceiver,當這個Activity銷毀的時候要主動撤銷註冊否則會出現異常。方法如下:
@Override protected void onDestroy() { // TODO Auto-generated method stub super.onDestroy(); //當Activity銷毀的時候取消註冊BroadcastReceiver unregisterReceiver(receiver); }
BroadcastReceiver的生命週期:
BroadcastReceiver的生命週期,從對象調用它開始,到onReceiver方法執行完成之後結束。另外,每次廣播被接收後會重新建立BroadcastReceiver對象,並在onReceiver方法中執行完就銷毀,如果BroadcastReceiver的onReceiver方法中不能在10秒內執行完成,Android會出現ANR異常。所以不要在BroadcastReceiver的onReceiver方法中執行耗時的操作。
如果需要在BroadcastReceiver中執行耗時的操作,可以通過Intent啟動Service來完成。但不能綁定Service。
特別是,您可能無法從一個BroadcastReceiver中顯示一個對話方塊,或綁定到服務。對於前者,則應該使用NotificationManager的API。對於後者,你可以使用Context.startService()來啟動一個Service。
廣播的類型:
Broadcast的類型有兩種:普通廣播和有序廣播。
Normal broadcasts(普通廣播):Normal broadcasts是完全非同步可以同一時間被所有的接收者接收到。訊息的傳遞效率比較高。但缺點是接收者不能講接收的訊息的處理資訊傳遞給下一個接收者也不能停止訊息的傳播。
Ordered broadcasts(有序廣播):Ordered broadcasts的接收者按照一定的優先順序進行訊息的接收。如:A,B,C的優先順序依次降低,那麼訊息先傳遞給A,在傳遞給B,最後傳遞給C。優先順序別聲明在<intent-filter>中,取值為[-1000,1000]數值越大優先順序別越高。優先順序也可通過filter.setPriority(10)方式設定。 另外Ordered broadcasts的接收者可以通過abortBroadcast()的方式取消廣播的傳播,也可以通過setResultData和setResultExtras方法將處理的結果存入到Broadcast中,傳遞給下一個接收者。然後,下一個接收者通過getResultData()和getResultExtras(true)接收高優先順序的接收者存入的資料。
應用執行個體:
發送並接收普通和有序廣播:
運行:
執行個體代碼:
MainActivity.java:發送廣播:
package com.jph.broadcastreceiverdemo;import android.os.Bundle;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.app.Activity;import android.content.Intent;/** * Describe:</br> * <br/>本執行個體有兩個優先順序別不同的廣播接收器 * <br/>通過發送普通廣播,和有序廣播來學習 * <br/>BroadcastReceiver的原理 * <br/>@author jph * <br/>@Date:2014.08.05 * */public class MainActivity extends Activity {MyBroadcastReceiver receiver;Button btnSend,btnSend2;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);btnSend=(Button)findViewById(R.id.btnSend);btnSend2=(Button)findViewById(R.id.btnSend2);receiver=new MyBroadcastReceiver();OnClickListener listener=new OnClickListener() {@Overridepublic void onClick(View v) {// TODO Auto-generated method stubswitch (v.getId()) {case R.id.btnSend:Intent intent=new Intent();intent.setAction("android.intent.action.MyBroadcastReceiver");intent.putExtra("msg", "我在發送廣播!這隻是一個普通的廣播," +"你們無法通過abortBroadcast()的方式停止廣播的傳播," +"也無法往Broadcast中存入資料因為它是非同步");sendBroadcast(intent);break;case R.id.btnSend2:Intent intent2=new Intent();intent2.setAction("android.intent.action.MyBroadcastReceiver");intent2.putExtra("msg", "我在發送個有序的廣播," +"你們可以通過abortBroadcast()的方式停止廣播的傳播," +"也可以往Broadcast中存入資料");sendOrderedBroadcast(intent2, null);break;default:break;}}};btnSend.setOnClickListener(listener);btnSend2.setOnClickListener(listener);}}MyBroadcastReceiver.java:接收廣播
package com.jph.broadcastreceiverdemo;import java.text.SimpleDateFormat;import java.util.Date;import android.content.BroadcastReceiver;import android.content.Context;import android.content.Intent;import android.widget.Toast;/** * Describe:</br> * <br/>@author jph * <br/>@Date:2014.08.05 * */public class MyBroadcastReceiver extends BroadcastReceiver {@Overridepublic void onReceive(Context context, Intent intent) {// TODO Auto-generated method stubString msg=intent.getExtras().get("msg").toString();setResultData("MyBroadcastReceiver接收到廣播");Toast.makeText(context,"時間:"+new SimpleDateFormat("yyyy-MM-dd hh.mm.ss").format(new Date())+"\nMyBroadcastReceiver收到Action名為:"+intent.getAction().toString()+"的廣播 \nComponent:"+intent.getComponent()+"\nmsg:"+msg,Toast.LENGTH_LONG).show();}}SecondBroadcastReceiver.java接收廣播
package com.jph.broadcastreceiverdemo;import java.text.SimpleDateFormat;import java.util.Date;import android.content.BroadcastReceiver;import android.content.Context;import android.content.Intent;import android.widget.Toast;/** * Describe:</br> * <br/>@author jph * <br/>@Date:2014.08.05 * */public class SecondBroadcastReceiver extends BroadcastReceiver {@Overridepublic void onReceive(Context context, Intent intent) {// TODO Auto-generated method stubString msg=intent.getExtras().get("msg").toString();String result=getResultData();Toast.makeText(context,"時間:"+new SimpleDateFormat("yyyy-MM-dd hh.mm.ss").format(new Date())+"\nSecondBroadcastReceiver收到Action名為:"+intent.getAction().toString()+"的廣播 \nComponent:"+intent.getComponent()+"\nmsg:"+msg+"\n上一個接受者傳來的reult:"+result,Toast.LENGTH_LONG).show();}}設定檔AndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.jph.broadcastreceiverdemo" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="18" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.jph.broadcastreceiverdemo.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><!-- 在設定檔中註冊MyBroadcastReceiver能夠匹配的Intent --><receiver android:name="com.jph.broadcastreceiverdemo.MyBroadcastReceiver"> <intent-filter android:priority="200"> <action android:name="android.intent.action.MyBroadcastReceiver"></action> <category android:name="android.intent.category.DEFAULT"></category> </intent-filter></receiver><!-- 在設定檔中註冊SecondBroadcastReceiver能夠匹配的Intent --><receiver android:name="com.jph.broadcastreceiverdemo.SecondBroadcastReceiver"> <intent-filter android:priority="100"> <action android:name="android.intent.action.MyBroadcastReceiver"></action> <category android:name="android.intent.category.DEFAULT"></category> </intent-filter></receiver> </application></manifest>