可以通过Context.registerReceiver() 动态注册一个实例,也可以在AndroidManifest.xml中静态注册。
1 boardcast的两种接受方式:
- Normal broadcasts (See Context.senBroadcase): 完全异步的。所有的接受者几乎同时运行。
- Ordered broadcasts (See Context.sendOrderedBroadcast):
每次一个接受者运行处理。当一个运行着处理完成后,可以把运行结果传递给下一个接受者,或者终止广播传播。
接受者的顺序可以通过 intent-filter中的android:priority属性来定义,相同属性值的接受者的优先级是随意的。
2 安全:
- Intent是全局的,确保Intent ACTION名字与其他app不冲突
- 当动态或者静态注册一个boardcast receiver时,其他的app都可以发送broadcast给这个recevicer。为了防止这点,通过设置android:exported = “false”
- 可以通过sendBoardcast(Intent)或类似方法发送boardcast。在ICE_CREAM_SANDWICH之后,可以通过Intent.setPackage限制发送到对应的app中。
如果LocalBroadcastManager,使用上面的安全问题都不会存在。 - 访问权限必须在sender和recevier中声明。
当Sender在sendBroad或者sendOrderedBroadcast中增加permission后,接受者需要在AndroidManifest.xml中uses-permission tag增加对应权限,才可以接受到此broadcast。
当Receiver在registerReceiver或者AndroidManifest.xml中的增加permission后,广播者需要在AndroidManifest.xml中uses-permission tag增加对应权限,才可以发送此broadcast到receiver。
3 Receiver Lifecycle:
BroadcastReceiver只有在执行onReceive(Context,Intent)才有效。一直执行完成,系统就认为此对象接受及不再active了。
onReceive()里面不能存在异步操作,因为我们需要返回函数值给支持异步操作,但是 BroadcastReceiver 可能不再active,系统可能在异步操作完成前已经杀掉了boardcast进程。
4 Process Lifecycle:
BroadcastReceiver在执行 onReceive时,被系统当做前台进程。
如果要处理longer-run的操作,可以结合Servie和BroadcastReceiver来保持进程的active。
5 Demo
功能:接收手机重启发送的广播,记录重启的次数
AndroidManifest.xml中的定义:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<application
<receiver android:name="com.lewi.broadcast.RobootReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
<action android:name="com.lewi.broadcast.rebootReceiver"/>
</intent-filter>
</receiver>
</application>
Receiver定义:
public class RobootReceiver extends BroadcastReceiver {
public final static String mTag = "RobootReceiver";
private SharedPreferences mPrefs;
@Override
public void onReceive(Context context, Intent intent) {
Log.i(mTag, "onReceive : --");
mPrefs = context.getSharedPreferences(Utils.SharedPreferencesName, Context.MODE_PRIVATE);
SharedPreferences.Editor ed = mPrefs.edit();
ed.putInt(Utils.RebootCount, mPrefs.getInt(Utils.RebootCount, 0) + 1);
ed.commit();
Toast.makeText(context, "Received reboot broadcast", Toast.LENGTH_SHORT).show();
}
}
通过AndroidManifest.xml中的定义可以看出,我们也可以通过sendboardcast去发送此Receiver接受的广播。格式如下:
Intent i = new Intent("com.lewi.broadcast.rebootReceiver");
sendBroadcast(i);
6 Reference:
http://developer.android.com/intl/zh-cn/reference/android/content/BroadcastReceiver.html