android四大组件---BroadCastReceiver


概述:


广播是一种广泛运用的在应用程序之间传输信息的机制 。而 BroadcastReceiver 用来接收来自系统和应用中的广播,是对发送出来的广播进行过滤接收并响应的一类组件。
在Android系统中,广播体现在方方面面,例如当开机完成后系统会产生一条广播,接收到这条广播就能实现开机启动服务的功能;当网络状态改变时系统会产生一条广播,接收到这条广播就能及时地做出提示和保存数据等操作;当电池电量改变时,系统会产生一条广播,接收到这条广播就能在电量低时告知用户及时保存进度,等等。

  BroadcastReceiver 自身并不实现图形用户界面,但是当它收到某个通知后, BroadcastReceiver 可以启动Activity 作为响应,或者通过 NotificationMananger 提醒用户,或者启动 Service 等等


广播之间信息的传递是通过Intent对象来传递的;由于这里能通知到所有的接收者,所以肯定不能利用显示调用,只有利用隐式调用Intent对象了。(这里的隐式调用,并不是真正意义上的Intent隐式调用,因为Intent隐式调用,当出现很多匹配应用时,会以列表形式提示用户选择一个启动,而这里不同的地方在于,当有很多匹配项时,会给所有的匹配项都发一个消息,我说隐式调用,只是方便大家理解构造Intent的方法,即必须利用构造隐式Intent的方法来构造)


实现:(以收到短信)


第一种方式:


(1)创建自己的BroadcastReceiver对象,我们需要继承android.content.BroadcastReceiver,并实现其onReceive方法。


public class MyBroadcastReceiver extends BroadcastReceiver {
    // action 名称
    String SMS_RECEIVED = "android.provider.Telephony.SMS_RECEIVED" ;
 
    public void onReceive(Context context, Intent intent) {
 
       if (intent.getAction().equals( SMS_RECEIVED )) {
           // 相关处理 : 地域变换、电量不足、来电来信;
       }
    }
}

(2) 系统注册:在 AndroidManifest.xml  中注册

注意,这种方式的注册是常驻型的,也就是说当应用关闭后,如果有广播信息传来,MyReceiver也会被系统调用而自动运行。

< receiver android:name = ".MyBroadcastReceiver" >
           < intent-filter android:priority = "1000" >     
<span style="white-space:pre">	</span>   <span style="white-space:pre">	</span>< action android:name = " android.provider.Telephony.SMS_RECEIVED" />
           </ intent-filter >
</ receiver > 
注意这个例子需要权限

< uses-permission android:name = "android.permission.RECEIVE_SMS" />

< uses-permission android:name = "android.permission.SEND_SMS" />


第二种方式:

// 广播接收者 - 广播的接收
private BroadcastReceiver myBroadcastReceiver = new BroadcastReceiver() {
       @Override
       public void onReceive(Context context, Intent intent) {
           // 相关处理,如收短信,监听电量变化信息
       }
    };

代码中注册:

比如在onResume()中registerReceiver,在onPause()中unregisterReceiver()。这种方式在程序不运行时是收不到广播的

myBroadcastReceiver receiver = new myBroadcastReceiver ();
IntentFilter filter = new IntentFilter(); 
filter.addAction("android.provider.Telephony.SMS_RECEIVED");
registerReceiver(receiver, filter);


 

使用的时候(短信是系统发出,如果自己要发送广播如下)

Intent intent = new Intent();
intent.setAction("android.provider.Telephony.SMS_RECEIVED");
sendBroadcast(intent);



生命周期

 

运行原理很简单如下图:


每次广播到来时 , 会重新创建 BroadcastReceiver 对象 , 并且调用 onReceive() 方法 , 执行完以后 , 该对象即被销毁 . 所以

BroadcastReceiver 里不能做一些比较耗时的操作 , 否侧会弹出 ANR 的对话框 .

不能在里面开子线程解决这个问题,因为 BroadcastReceiver 的生命周期很短 , 子线程可能还没有结束

BroadcastReceiver 就先结束了 .BroadcastReceiver 一旦结束 , 此时 BroadcastReceiver 的

所在进程很容易在系统需要内存时被优先杀死 , 那么正在工作的子线程也会被杀死 

解决方法:

如果需要完成一项比较耗时的工作 , 应该通过发送 Intent 给 Service, 由 Service 来完成 。也可以跳转Activity,在Activity里面开线程做耗时工作。

比如:

public class AlarmReceiver extends BroadcastReceiver {
	@Override
	public void onReceive(Context context, Intent intent) {
		if (intent.getAction().equals("android.hjnote.ALARM_ACTION")) {
			<strong>Intent noteList = new Intent(context, AlarmActivity.class);
			noteList.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
			context.startActivity(noteList);</strong>
		}
	}
}


广播类型:

参考http://blog.csdn.net/liuhe688/article/details/6955668

普通广播(Normal Broadcast)

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

 

有序广播(Ordered Broadcast)

有序广播比较特殊,它每次只发送到优先级较高的接收者那里,然后由优先级高的接受者再传播到优先级低的接收者那里,优先级高的接收者有能力终止这个广播。


有序广播的注册:


AndroidMainfest.xml文件:

[html]  view plain copy
  1. <receiver android:name=".FirstReceiver">  
  2.     <intent-filter android:priority="1000">  
  3.         <action android:name="android.intent.action.MY_BROADCAST"/>  
  4.         <category android:name="android.intent.category.DEFAULT" />  
  5.     </intent-filter>  
  6. </receiver>  
  7. <receiver android:name=".SecondReceiver">  
  8.     <intent-filter android:priority="999">  
  9.         <action android:name="android.intent.action.MY_BROADCAST"/>  
  10.         <category android:name="android.intent.category.DEFAULT" />  
  11.     </intent-filter>  
  12. </receiver>  
  13. <receiver android:name=".ThirdReceiver">  
  14.     <intent-filter android:priority="998">  
  15.         <action android:name="android.intent.action.MY_BROADCAST"/>  
  16.         <category android:name="android.intent.category.DEFAULT" />  
  17.     </intent-filter>  
  18. </receiver>  
我们看到,现在这三个接收者的<intent-filter>多了一个android:priority属性,并且依次减小。这个属性的范围在-1000到1000,数值越大,优先级越高。

发送普通广播:sendBroadcast(intent); 

发送有序广播:sendOrderedBroadcast(intent, receiverPermission);

注意,receiverPermission发送有序广播时需要一个权限参数。

如果为null则表示不要求接收者声明指定的权限,如果不为null,则表示接收者若要接收此广播,需声明指定权限。这样做是从安全角度考虑的,例如系统的短信就是有序广播的形式,一个应用可能是具有拦截垃圾短信的功能,当短信到来时它可以先接受到短信广播,发现是垃圾短信的时候终止广播传递(也就是拦截功能),这样的软件就必须声明接收短信的权限。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值