一、Broadcast(广播)
是一种广泛应用在应用程序之间传输信息的机制。
二、Broadcast(广播接收器)
是对发送出来的广播进行过滤接收并响应的一类组件,它就是用来接收来自系统和应用中的广播。
在Android系统中,广播体现在方方面面,例如当开机完成后系统会产生一条广播,接收到这条广播就能实现开机启动服务的功能;当网络状态改变时系统会产生一条广播,接收到这条广播就能及时地做出提示和保存数据等操作;当电池电量改变时,系统会产生一条广播,接收到这条广播就能在电量低时告知用户及时保存进度,等等。
Android中的广播机制设计的非常出色,很多事情原本需要开发者亲自操作的,现在只需等待广播告知自己就可以了,大大减少了开发的工作量和开发周期。而作为应用开发者,就需要数练掌握Android系统提供的一个开发利器,那就是BroadcastReceiver。下面我们就对BroadcastReceiver逐一地分析和演练,了解和掌握它的各种功能和用法。
注意:
1、BroadcastReceiver生命周期很短,如果超时了,系统会当当前广播为一个失败的请求。
2、BroadcastReceiver不能做一些比较耗时的操作。
3、应该通过发送Intent给Service,由Service来完成。
4、不能使用子线程。
三、广播的分类
1、普通广播(Normal Broadcasts):
所有监听该广播的广播接收者都可以接受到该广播。
特点:
1)同级别接收先后是随机的(无序)。
2)级别低的后接受到广播。
3)接收器不能截断广播的继续广播也不能处理广播。
4)同级别动态注册高于静态注册。
2、有序广播(Ordered Broadcasts):
按照接受者的优先顺序接收广播,有限级别在intent-filter中的priority中声明,-1000-2000之间,值越大,优先级越高。可以终止广播意图的继续传播。接受者可以纂改内容。
特点:
1)同级别接收顺序是随机的。
2)能截断广播的继续传播,高级别的广播接收器收到广播后,可以决定是否把广播截断。
3)接收器能截断广播的继续传播,也能处理广播。
4)同级别动态注册高于静态注册。
3、异步广播(粘滞性滞留广播):
不能将处理结果传给下一个接受者,无法终止广播,会滞留在内存中,需要手动释放资源。
四、实例代码:
三种广播的特点。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <Button android:id="@+id/btn1_send" android:onClick="doSend" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="发送一条普通广播" /> <Button android:id="@+id/btn2_send" android:onClick="doSend" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="发送一条有序广播" /> <Button android:id="@+id/btn3_send" android:onClick="doSend" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="发送一条异步广播" /> </LinearLayout>
页面后台代码:main.java
package com.example.broadcastreceiverdemo; import android.os.Bundle; import android.app.Activity; import android.content.Intent; import android.content.IntentFilter; import android.view.Menu; import android.view.View; public class MainActivity extends Activity { BC_3 bc3; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //动态注册,动态注册的优先级高于静态注册 /*IntentFilter filter = new IntentFilter("BC_One"); BC_2 bc2 = new BC_2(); registerReceiver(bc2, filter);*/ } public void doSend(View view){ //创建一个intent对象 Intent intent = new Intent(); switch(view.getId()){ case R.id.btn1_send: //设置intent的值 intent.putExtra("msg", "这是btn1发送的一条普通广播"); //设置Action标记,用于过滤使用 intent.setAction("BC_One"); //发送普通广播 sendBroadcast(intent); break; case R.id.btn2_send: //设置intent的值 intent.putExtra("msg", "这是btn2发送的一条有序广播"); //设置Action标记,用于过滤使用 intent.setAction("BC_One"); //发送有序广播 sendOrderedBroadcast(intent, null); break; case R.id.btn3_send: //设置intent的值 intent.putExtra("msg", "这是btn3发送的一条异步广播"); //设置Action标记,用于过滤使用 intent.setAction("BC_Three"); //发送异步广播 sendStickyBroadcast(intent); //先发送广播,后添加广播接收器 IntentFilter filter = new IntentFilter("BC_Three"); bc3 = new BC_3(); registerReceiver(bc3, filter); break; } } @Override protected void onDestroy() { super.onDestroy(); //销毁驻留内存中的接收器 unregisterReceiver(bc3); } }
自定义广播接收类bc_1.java
package com.example.broadcastreceiverdemo; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.os.Bundle; //定义一个广播接收器,必须实现onReceive方法 public class BC_1 extends BroadcastReceiver{ @Override public void onReceive(Context context, Intent intent) { System.out.println("bc1接收到的广播:" + intent.getStringExtra("msg")); //获取BC_2中处理的广播内容 Bundle bundle = getResultExtras(true); System.out.println("获取追加后的数据:" + bundle.getString("appendStr")); } }
第二个广播接受类:bc_2.java
package com.example.broadcastreceiverdemo; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.os.Bundle; //定义一个广播接收器,必须实现onReceive方法 public class BC_2 extends BroadcastReceiver{ @Override public void onReceive(Context context, Intent intent) { System.out.println("bc2接收到的广播:" + intent.getStringExtra("msg")); //截断广播,只有有序广播才可以被截断,普通广播无法被截断。 //abortBroadcast(); //处理广播,在广播中追加数据,只有有序广播可以处理,普通广播无法处理 Bundle bundle = new Bundle(); bundle.putString("appendStr", "追加的广播数据"); setResultExtras(bundle); //将追加的数据追加的广播中 } }
第三个广播接收类:接收异步广播,bc_3.java
package com.example.broadcastreceiverdemo; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.os.Bundle; //定义一个广播接收器,必须实现onReceive方法 public class BC_3 extends BroadcastReceiver{ @Override public void onReceive(Context context, Intent intent) { System.out.println("bc3接收到的广播:" + intent.getStringExtra("msg")); } }
配置文件:如果是静态注册,需要在配置文件中注册广播接收器和过滤条件。如果是异步注册,需要打开异步滞留权限。
<?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="18" /> <!-- 异步广播驻留权限 --> <uses-permission android:name="android.permission.BROADCAST_STICKY"/> <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="com.example.broadcastreceiverdemo.BC_1"> <!-- priority:设置广播的优先级,数字越大,级别越高 --> <intent-filter android:priority="100"> <!-- 设置接收广播的过滤器,必须和发送时广播的action一致 --> <action android:name="BC_One"></action> </intent-filter> </receiver> <receiver android:name="com.example.broadcastreceiverdemo.BC_2"> <intent-filter android:priority="200"> <action android:name="BC_One"></action> </intent-filter> </receiver> </application> </manifest>