BroadcastReceiver 简介
广播接收者( BroadcastReceiver )用于接收广播 Intent ,广播 Intent 的发送是通过调用Context.sendBroadcast() 、 Context.sendOrderedBroadcast() 、 Context.sendStickyBroadcast()来实现的。通常一个广播 Intent 可以被订阅了此 Intent 的多个广播接收者所接收(就像真的收音机一样)。
广播(Broadcas)是一种广泛运用的在应用程序之间传输信息的机制 。而 广播接收者(BroadcastReceiver)是对发送出来的广播进行过滤接收并响应的一类组件。
来自普通应用程序,如一个应用程序通知其他应用程序某些数据已经下载完毕。
BroadcastReceiver 自身并不实现图形用户界面,但是当它收到某个通知后, BroadcastReceiver 可以启动Activity 作为响应,或者通过 NotificationMananger 提醒用户,或者启动 Service 等等。
BroadcastReceiver 广泛应用与应用间的交流。官方文档有这么一段话:
If you don't need to send broadcasts across applications, consider using this class with LocalBroadcastManager instead of the more general facilities described below. This will give you a much more efficient implementation (no cross-process communication needed) and allow you to avoid thinking about any security issues related to other applications being able to receive or send your broadcasts.
BroadcastReceiver生命周期
每次广播到来时 , 会重新创建 BroadcastReceiver 对象 , 并且调用 onReceive() 方法 , 执行完以后 , 该对象即被销毁 . 当 onReceive() 方法在 10 秒内没有执行完毕,就会导致ANR。如果需要执行长任务,那么就有必要使用Service。千万不要使用新线程,这是很危险的事情。因为有可能线程没有执行完,BroadcastReceiver就挂了。注册BroadcastReceiver
先来说说怎样接收广播。如其他组件一样,BroadcastReceiver是要注册的,但是不同的是,BroadcastReceiver可以动态注册,也可以静态注册。静态注册
和其他组件一样,在AndroidMainfest.xml里面直接声明,这样在整个应用运行过程中,这个广播都处于注册状态,每时每刻都能收到指定广播Action。
<receiver android:name=".MyBroadcastReceiver" >
<intent-filter android:priority="1000" >
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
</receiver>
当然,要能正常监听到广播,还得加上权限声明:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
这样,一个静态的广播就注册好了。当然你也可以不定义action,那样你有权限收到的广播,都会收到,但是这样有一个问题就是,你收到不必要的广播也会启动BroadcastReceiver占用资源 ,而且还得自己过滤,比较麻烦,所以在最好把你需要的广播定义在intent-filter里面。action可以定义不止一个,可以定义多个,一个BroadcastReceiver可以监听多种广播,就像收音机有多个频道一样。
public class MyBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
ConnectivityManager connectivityManager = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetInfo = connectivityManager.getActiveNetworkInfo();
if(activeNetInfo == null) {
sLog("无网络状态");
} else {
switch(activeNetInfo.getType()) {
case ConnectivityManager.TYPE_WIFI:
sLog("WIFI状态");
break;
default :
sLog("3G/2G状态");
break;
}
}
}
private void sLog(String msg) {
Log.e("NetworkChangeReceiver", msg);
}
}
注意了,该类必须是public的。

动态注册
public class MainActivity extends Activity {
private MyBroadcastReceiver receiver = new MyBroadcastReceiver();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
IntentFilter filter = new IntentFilter();
filter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
this.registerReceiver(receiver, filter);
}
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(receiver);
}
}
逻辑上与AndroidMainifest注册是一样的,不过动态注册要注意生命周期问题,记得要调用注销unregisterReceiver()。当然,你也可以在Activity生命周期其他阶段调用,但必须要对应。
发送Broadcast
同步广播(也叫“普通广播”,Context.sendBroadcast()):
发送方发出后,几乎同时到达多个广播接收者处,某个接收者不能接收到广播后进行一番处理后传给下一个接收者,并且无法终止广播继续传播。也就是说,每个广播接收者所收到的广播都是一模一样的,没有应用能够对其进行窜改。
有序广播(Context.sendOrderedBroadcast()):
广播接收者需要提前设置优先级,优先级高的先接收到广播,优先级数值为-1000~1000,在AndroidManifest.xml的<intent-filter android:priority="xxx">设置;比如存在3个广播接收者A、B、C,优先级A>B>C,因此A最先收到广播,当A收到广播后,可以向广播中添加一些数据给下一个接收者(intent.putExtra()),或者终止广播(在当前BroadcastReceiver内调用方法 abortBroadcast() );
异步广播(Context.sendStickyBroadcast()):同步广播(Context.sendBroadcast())
Intent intent = new Intent();
intent.setAction("com.plusjun.test.hahaha");
intent.putExtra("name", "xiazdong");
MainActivity.this.sendBroadcast(intent);
一个广播就完成了。
有序广播(Context.sendOrderedBroadcast())
如下代码Intent intent = new Intent();
intent.setAction("com.plusjun.test.hahaha");
intent.putExtra("name", "xiazdong");
MainActivity.this.sendOrderedBroadcast(intent, null);
这就是有序广播。
public class MyReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String name = intent.getExtras().getString("name");
Log.i("Recevier", "接收到:"+name);
abortBroadcast(); //Receiver接收到广播后中断广播
}
}
异步广播(Context.sendStickyBroadcast()):
能力有限了,无法解说。找个时间再研究研究。
摘抄官方原文:
public voidsendStickyBroadcast(Intent intent)
Added in API level 1
该方法需要拥有 BROADCAST_STICKY 权限。
Perform a sendBroadcast(Intent) that is "sticky," meaning the Intent you are sending stays around after the broadcast is complete, so that others can quickly retrieve that data through the return value ofregisterReceiver(BroadcastReceiver, IntentFilter). In all other ways, this behaves the same assendBroadcast(Intent).
You must hold the BROADCAST_STICKY permission in order to use this API. If you do not hold that permission,SecurityException will be thrown.
需要收听权限的广播
sendOrderedBroadcast(new Intent("com.plusjun.test.hahaha"), "com.plusjun.test");
代码中与上述例子最大的差别在于Activity中发送广播的方法:
sendOrderedBroadcast(new Intent("com.plusjun.test.hahaha"), "com.plusjun.test");
在第二个参数增加了一个字符串。
在发起广播的应用中,需要在AndroidManifest文件中配置自定义的权限:
<permission android:protectionLevel="normal" android:name="com.plusjun.test"></permission>
相应的,接收器所在的应用中必须设置接收权限:
<uses-permission android:name="com.plusjun.test"></uses-permission>
这样,接收器就可以正确接收到广播了。
http://my.eoe.cn/lqgyt1/archive/1902.html
http://yangguangfu.iteye.com/blog/1063732
在此表示感谢。
转载请注明来源,版权归原作者所有,未经同意严禁用于任何商业用途。
微博:http://weibo.com/theworldsong
邮箱:theworldsong@foxmail.com