Android四大组件----BroadcastReceiver

来源:互联网 发布:海贼王的主题知乎 编辑:程序博客网 时间:2024/05/17 01:42

一、什么是BroadcastReceiver?

就是广播接收者,用于接收广播的Intent,可以接收应用程序发出的广播,也可以是系统发出的,如电量变化、插拔耳机、开机完成等等,然后再做相应的事件处理,其广泛应用于应用程序间的信息传输。

二、有哪几种广播?

1、普通广播

对于多个接收者来说是完全异步的,通常每个接收者都无需等待即可以接收到广播,接收者相互之间不会有影响。对于这种广播,接收者无法终止广播,即无法阻止其他接收者的接收动作。

2、有序广播

按照接收者的优先级顺序接收广播 , 优先级别在 intent-filter 中的 priority 中声明, 也可以在代码中设定,-1000 到1000 之间 ,值越大,优先级越高 。可以终止广播意图的继续传播,接收者可以篡改内容。

3、常驻广播

异步广播在发送者发出后,会一直存放在系统中,任何后续注册的BroadcastReceiver都可以继续处理该broadcast。广播发送者可以去除该广播。

三、生命周期

生命周期只有十秒左右,如果在 onReceive() 内做超过十秒的事情,就会报错 。每次广播到来时 , 会重新创建 BroadcastReceiver 对象 , 并且调用 onReceive() 方法 , 执行完以后 , 该对象即被销毁 。当 onReceive() 方法在 10 秒内没有执行完毕, Android 会认为该程序无响应。所以在BroadcastReceiver 里不能做一些比较耗时的操作。

四、发送广播需要注册,如何注册?

1、静态注册

在AndroidManifest.xml中用标签声明注册,并在标签内用标签设置过滤器,这种注册方式是常驻型的。

                 <receiverandroid:name=".StaticReceiver">                     <intent-filter>                         <actionandroid:name="com.example.print"></action>                     </intent-filter>                 </receiver>

2、动态注册

动态注册方式在activity或service里面调用函数来注册,和静态的内容差不多,一个形参是receiver,另一个是IntentFilter,其中里面是要接收的action。

                     IntentFilter filter = newIntentFilter();                     filter.addAction(ACTION_PRINT);                     registerReceiver(myReceiver,filter);

去注册

         unregisterReceiver(myReceiver);

一般:在onStart中注册,onStop中取消unregisterReceiver

五、广播的发送

1、普通广播

sendBroadcast(intent),该函数有多种构造,我们已最简单的做介绍,下同

                             Intentintent = new Intent();                             intent.setAction(ACTION_PRINT);                             sendBroadcast(intent);

2、有序广播

sendOrderedBroadcast(intent, receiverPermission),receiverPermission是权限,一个接收器必须持有该权限才能接收到广播,可以为null。

                Intent intent = new Intent();                             intent.setAction(ACTION_PRINT);                             sendOrderedBroadcast(intent,null);

3、常驻广播

sendStickyBroadcast(intent),该广播需要权限android.permission.BROADCAST_STICKY才能发送,去除广播用removeStickyBroadcast(intent),同样也需要权限,不再举例。

另外,sendStickyOrderedBroadcast这个广播既有常驻广播的特性也具有有序广播的特性,我们可以称为常驻有序广播

六、广播的接收和处理

创建BroadcastReceiver对象,并且实现onReceive方法,然后可以在onReceive方法中根据不同的广播事件进行相应的处理。

16.      

package com.example.broadcastreceiverdemo;               import android.content.BroadcastReceiver;       import android.content.Context;       import android.content.Intent;       import android.os.Bundle;       import android.util.Log;               public class StaticReceiver extendsBroadcastReceiver {          privatestatic final String TAG = "kingfong";          privatestatic final String ACTION_PRINT = "com.example.print";                  @Override          publicvoid onReceive(Context context, Intent intent) {                   //TODO Auto-generated method stub                   StringintentAction = intent.getAction();                   if(intentAction.equals(ACTION_PRINT)){                             Bundleb = intent.getExtras();                             Log.d(TAG,"StaticReceiver:Ihave received the boradcast");                   }          }      }

1、普通广播

各个BroadcastReceiver对象处理广播顺序并不固定,和注册广播的顺序有关系,相互之间互不影响。在onReceive中做一些简单的处理,但不要太耗时。如果需要做大量的工作,需要启动service来处理。这里不能使用子线程来解决 , 因为 BroadcastReceiver 的生命周期很短 , 子线程可能还没有结束BroadcastReceiver 就先结束了,BroadcastReceiver 一旦结束,此时 BroadcastReceiver 的所在进程很容易在系统需要内存时被优先杀死 ,因为它属于空进程 ( 没有任何活动组件的进程 ),如果它的宿主进程被杀死,那么正在工作的子线程也会被杀死 . 所以采用子线程来解决是不可靠的。

2、有序广播

有序广播发送时一般需要带权限参数,如果为null则表示不要求接收者声明指定的权限,如果不为null,则表示接收者若要接收此广播,需声明指定权限。接收者会按照优先级大小先后处理该广播,优先级可以在注册时IntentFilter的android:priority参数指定,也可以在代码中设置,这个属性的范围在-1000到1000,数值越大,优先级越高。高优先级可以调用以下接口终止该广播的传递。

优先级设定

               <receiverandroid:name=".StaticReceiver">                   <intent-filterandroid:priority="100">                       <actionandroid:name="com.example.print"></action>                   </intent-filter>               </receiver>

                           IntentFilterfilter = new IntentFilter();                   filter.addAction(ACTION_PRINT);                   filter.setPriority(200);                   registerReceiver(myReceiver,filter);

   终止广播传递

                             if(isOrderedBroadcast()){                                                                      abortBroadcast();                             }

3、常驻广播

常驻广播发送后,在发送者清除之前,任何时候注册的BroadcastReceiver都可以接收该广播,并做处理。

七、常用API接口

       public abstract void onReceive(Contextcontext, Intent intent);       public final void setResultCode(int code)       public final int getResultCode()       public final void setResultData(String data)       public final String getResultData()       public final void setResultExtras(Bundleextras)       public final Bundle getResultExtras(booleanmakeMap)       public final void setResult(int code, Stringdata, Bundle extras)       public final boolean getAbortBroadcast()       public final void abortBroadcast()       public final void clearAbortBroadcast()       public final boolean isOrderedBroadcast()       public final boolean isInitialStickyBroadcast()

八、代码实例

1、MainActivity,设置button事件,注册发送广播

<pre name="code" class="java">package com.example.broadcastreceiverdemo;import android.os.Bundle;import android.app.Activity;import android.content.BroadcastReceiver;import android.content.Intent;import android.content.IntentFilter;import android.util.Log;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;public class MainActivity extends Activity implements OnClickListener{private static final String TAG = "kingfong";private BroadcastReceiver myReceiver;private static final String ACTION_PRINT = "com.example.print";private Button sendButton;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main);sendButton = (Button)findViewById(R.id.send);sendButton.setOnClickListener(this);myReceiver = new DynamicReceiver();}public void onClick(View v){switch(v.getId()){case R.id.send:Intent intent = new Intent();intent.setAction(ACTION_PRINT);//设置广播actionintent.putExtra("msg", "Hello,I am comming");//intent可携带数据sendBroadcast(intent);//发送普通广播sendOrderedBroadcast(intent, null);//发送有序广播}}@Overrideprotected void onStart() {// TODO Auto-generated method stubsuper.onStart();IntentFilter filter = new IntentFilter();filter.addAction(ACTION_PRINT);//添加广播过滤条件,意思是说可以接受到发送的ACTION_PRINT广播,可以添加多条actionfilter.setPriority(200);//设置广播优先级registerReceiver(myReceiver, filter);//广播注册}@Overrideprotected void onStop() {// TODO Auto-generated method stubsuper.onStop();unregisterReceiver(myReceiver);//去注册}}

2、StaticReceiver接收静态注册的广播

</pre><pre name="code" class="java">package com.example.broadcastreceiverdemo;import android.content.BroadcastReceiver;import android.content.Context;import android.content.Intent;import android.os.Bundle;import android.util.Log;public class StaticReceiver extends BroadcastReceiver {private static final String TAG = "kingfong";private static final String ACTION_PRINT = "com.example.print";@Overridepublic void onReceive(Context context, Intent intent) {//在onReceive中处理接收的广播// TODO Auto-generated method stubString intentAction = intent.getAction();//获取actionif(intentAction.equals(ACTION_PRINT)){//根据接受到的action做不同的处理(此处只有一个action)Bundle b = intent.getExtras();//获取广播携带的数据String str = b.getString("msg");Log.d(TAG,"StaticReceiver:I have received the boradcast"+str);}}}

3、DynamicReceiver接收动态注册的广播

</pre><pre name="code" class="java">package com.example.broadcastreceiverdemo;import android.content.BroadcastReceiver;import android.content.Context;import android.content.Intent;import android.util.Log;public class DynamicReceiver extends BroadcastReceiver {private static final String TAG = "kingfong";private static final String ACTION_PRINT = "com.example.print";@Overridepublic void onReceive(Context context, Intent intent) {// TODO Auto-generated method stubString intentAction = intent.getAction();if(intentAction.equals(ACTION_PRINT)){Log.d(TAG,"DynamicReceiver have received the boradcast");if(isOrderedBroadcast()){//判断是否为有序广播abortBroadcast();//终止广播}}}}

4、AndroidManifest.xml注册了StaticReceiver用于接收静态注册广播

<pre name="code" class="java"><?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"    package="com.example.broadcastreceiverdemo"    android:versionCode="1"    android:versionName="1.0" >    <uses-sdk        android:minSdkVersion="8"        android:targetSdkVersion="17" />    <application        android:allowBackup="true"        android:icon="@drawable/ic_launcher"        android:label="@string/app_name"        android:theme="@style/AppTheme" >        <activity            android:name="com.example.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>        <!-- 注册静态广播  -->        <receiver android:name=".StaticReceiver">             <intent-filter android:priority="100">                 <action android:name="com.example.print"></action>             </intent-filter>         </receiver>     </application></manifest>

点击send键,log打印结果如下

D/kingfong( 9370): DynamicReceiver havereceived the boradcast

D/kingfong( 9370): StaticReceiver:I havereceived the boradcastHello,I am comming

D/kingfong( 9370): DynamicReceiver havereceived the boradcast

我们看到StaticReceiver只接收了一次广播,这是因为DynamicReceiver在接收有序广播后将广播终止了,所以StaticReceiver就接收不到了。

 

 

 


0 0