广播接收者与广播发送者复习
2017-01-23 15:50
531 查看
广播接收者的本质就是一个全局的监听器,用于监听系统全局的广播消息,比如:拨打电话、收发短信、屏幕解锁等事件产生了,系统会发送广播,只要应用程序接受到这条广播,就知道系统发生了相应的事件,从而执行相应的代码。
创建一个广播接收者:
声明一个类继承自BroadcastReceiver,重写BroadcastReceiver的onReceiver方法即可。
指定BroadcastReceiver可以匹配的Intent:
a.在清单文件中进行指定
b.使用代码动态指定(特殊的广播接收者必须使用代码的方式进行动态指定)
下面创建一个广播接收者:
1.声明一个类继承自BroadcastReceiver,重写BroadcastReceiver的onReceiver方法即可。
2.在清单文件中进行配置(application节点下):
注:一个广播接收者可以监听多个事件,此处监听了电话状态的改变,接收短信。此处还需要添加上两个权限:
当配置的action 的事件发生了 onReceive方法就会执行
运行效果:
对于一些比较频繁的广播事件比如屏幕解锁,锁屏,电池电量变化,这样的广播接收者在清单文件里面注册无效。需要使用代码进行动态注册
监听屏幕锁屏事件的广播接收者:
1.声明一个类继承自BroadcastReceiver,重写BroadcastReceiver的onReceiver方法即可。
f35c
2.在MainActivity中对要监听的事件进行动态的注册:
在MainActivity销毁的时候,一定unregisterReceiver(specialReceiver)
,对广播接收者取消注册。
否则会报下面的错误:
运行效果:
这样子做的话如果MainActivity销毁之后,也就是广播接收者取消注册了,就不会再监听到锁屏状态的变化了,这应该也是谷歌出于保证系统流畅度的设计,避免程序间的唤醒以达到节省内存的目的,如果需要时刻监听这种比较频繁的广播事件则可以再Service中进行动态注册。
广播发送者:
广播既可以由Android系统进行发送,也可以由我们自己的程序来向外发送广播。
在程序中发送广播十分简单,只需要调用Context的sendBroadcast(Intent intent)
方法即可,这条广播将会启动intent参数所对应的BroadcastReceiver.
广播分为:
无序广播:通过Context.sendBroadcast()方法来发送,所有的广播接收者(BroadcastReceiver)的接收顺序不确定,这种方式的效率更高,但是但BroadcastReceiver无法使用setResult系列、getResult系列及abort(中止)系列API。
有序广播:是通过Context.sendOrderedBroadcast来发送,所有的receiver依次执行。
BroadcastReceiver可以使用setResult系列函数来结果传给下一个BroadcastReceiver,通过getResult系列函数来取得上个BroadcastReceiver返回的结果,并可以abort系列函数来让系统丢弃该广播,使用该广播不再传送到别的BroadcastReceiver。
可以通过在intent-filter中设置android:priority属性来设置receiver的优先级,优先级相同的receiver其执行顺序不确定。
如果BroadcastReceiver是代码中注册的话,且其intent-filter拥有相同android:priority属性的话,先注册的将先收到广播。
简要概述:
无序广播:广播不可以被终止 数据不可以被修改
有序广播:按照优先级一级一级的接收 有序广播可以被终止 数据可以被修改
发送一个无序广播:
发送一个有序广播:
FinalReceiver.java
接收一个有序广播:
创建4个广播接收者用于测试:
在清单文件中进行配置:
这里只写出第一个广播接收者,其它的代码与之相同。
运行效果:
可以看到每个广播接收者按照清单文件中配置的优先级依次接收
使用setResult修改广播发送的内容:
SecondReceiver.Java
使用abortBroadcast( )进行广播的截断
ThirdReceiver.Java
运行效果:
可见在 ThirdReceiver 获取的内容为SecondReceiver修改过
的,FourthReceiver因为广播在ThirdReceiver中被截断了,所以没有收到广播,FinalReceiver为最后执行的广播。
┭┮﹏┭┮ O(∩_∩)O
创建一个广播接收者:
声明一个类继承自BroadcastReceiver,重写BroadcastReceiver的onReceiver方法即可。
指定BroadcastReceiver可以匹配的Intent:
a.在清单文件中进行指定
b.使用代码动态指定(特殊的广播接收者必须使用代码的方式进行动态指定)
下面创建一个广播接收者:
1.声明一个类继承自BroadcastReceiver,重写BroadcastReceiver的onReceiver方法即可。
/** * Created by 春水碧于天 on 2017/1/22. */ public class SmsReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if(action.equals("android.provider.Telephony.SMS_RECEIVED")){ Toast.makeText(context,"来信息了!",Toast.LENGTH_SHORT).show(); }else if(action.equals("android.intent.action.PHONE_STATE")){ Toast.makeText(context,"来电话了!",Toast.LENGTH_SHORT).show(); } } }
2.在清单文件中进行配置(application节点下):
<receiver android:name=".SmsReceiver"> <intent-filter> <action android:name="android.provider.Telephony.SMS_RECEIVED"/> <action android:name="android.intent.action.PHONE_STATE"/> </intent-filter> </receiver>
注:一个广播接收者可以监听多个事件,此处监听了电话状态的改变,接收短信。此处还需要添加上两个权限:
<uses-permission android:name="android.permission.RECEIVE_SMS"/> <uses-permission android:name="android.permission.READ_PHONE_STATE" />
当配置的action 的事件发生了 onReceive方法就会执行
运行效果:
对于一些比较频繁的广播事件比如屏幕解锁,锁屏,电池电量变化,这样的广播接收者在清单文件里面注册无效。需要使用代码进行动态注册
监听屏幕锁屏事件的广播接收者:
1.声明一个类继承自BroadcastReceiver,重写BroadcastReceiver的onReceiver方法即可。
f35c
/** * Created by 春水碧于天 on 2017/1/22. */ public class SpecialReceiver extends BroadcastReceiver{ @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if(action.equals("android.intent.action.SCREEN_ON")){ Toast.makeText(context,"屏幕解锁了",Toast.LENGTH_SHORT).show(); }else if(action.equals("android.intent.action.SCREEN_OFF")){ Toast.makeText(context,"屏幕锁屏了",Toast.LENGTH_SHORT).show(); } } }
2.在MainActivity中对要监听的事件进行动态的注册:
public class MainActivity extends AppCompatActivity { private SpecialReceiver specialReceiver; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //动态的去注册屏幕解锁和锁屏的广播 IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction("android.intent.action.SCREEN_ON"); intentFilter.addAction("android.intent.action.SCREEN_OFF"); //创建一个广播接收者的实例 specialReceiver = new SpecialReceiver(); /** * 参数1:BroadcastReceiver receiver: * 参数2:IntentFilter filter */ registerReceiver(specialReceiver,intentFilter); } @Override protected void onDestroy() { super.onDestroy(); //动态注册的广播收者一定都要取消注册才行 unregisterReceiver(specialReceiver); } }
在MainActivity销毁的时候,一定unregisterReceiver(specialReceiver)
,对广播接收者取消注册。
否则会报下面的错误:
Activity com.example.reviewbroadcastreciver.MainActivity has leaked IntentReceiver com.example.reviewbroadcastreciver.SpecialReceiver@752c889 that was originally registered here. Are you missing a call to unregisterReceiver()?
运行效果:
这样子做的话如果MainActivity销毁之后,也就是广播接收者取消注册了,就不会再监听到锁屏状态的变化了,这应该也是谷歌出于保证系统流畅度的设计,避免程序间的唤醒以达到节省内存的目的,如果需要时刻监听这种比较频繁的广播事件则可以再Service中进行动态注册。
广播发送者:
广播既可以由Android系统进行发送,也可以由我们自己的程序来向外发送广播。
在程序中发送广播十分简单,只需要调用Context的sendBroadcast(Intent intent)
方法即可,这条广播将会启动intent参数所对应的BroadcastReceiver.
广播分为:
无序广播:通过Context.sendBroadcast()方法来发送,所有的广播接收者(BroadcastReceiver)的接收顺序不确定,这种方式的效率更高,但是但BroadcastReceiver无法使用setResult系列、getResult系列及abort(中止)系列API。
有序广播:是通过Context.sendOrderedBroadcast来发送,所有的receiver依次执行。
BroadcastReceiver可以使用setResult系列函数来结果传给下一个BroadcastReceiver,通过getResult系列函数来取得上个BroadcastReceiver返回的结果,并可以abort系列函数来让系统丢弃该广播,使用该广播不再传送到别的BroadcastReceiver。
可以通过在intent-filter中设置android:priority属性来设置receiver的优先级,优先级相同的receiver其执行顺序不确定。
如果BroadcastReceiver是代码中注册的话,且其intent-filter拥有相同android:priority属性的话,先注册的将先收到广播。
简要概述:
无序广播:广播不可以被终止 数据不可以被修改
有序广播:按照优先级一级一级的接收 有序广播可以被终止 数据可以被修改
发送一个无序广播:
//发送一个无序广播 public void Click(View v){ Intent intent = new Intent(); intent.setAction("com.example.reviewbroadcastreciver"); intent.putExtra("msg","你妈叫你们回家吃饭啦……"); sendBroadcast(intent); }
发送一个有序广播:
//发送一个有序广播 //发送一个有序广播 public void OrderClick(View v){ Intent intent = new Intent(); intent.setAction("com.example.reviewbroadcastreciver"); //第三个参数为最终要执行的广播接收者 sendOrderedBroadcast(intent, null, new FinalReceiver(), null, 1, "你妈叫你回家吃饭了!", null); } }
FinalReceiver.java
/** * 最终执行的Receiver,不需要在清单文件中配置 * Created by 春水碧于天 on 2017/1/23. */ public class FinalReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { String msg = getResultData(); Toast.makeText(context,"报告奶奶,爸爸妈妈都叫我回家吃饭了!",Toast.LENGTH_SHORT).show(); } }
接收一个有序广播:
创建4个广播接收者用于测试:
在清单文件中进行配置:
<receiver android:name=".FirstReceiver"> <!--设置接收广播的优先级--> <intent-filter android:priority="1000"> <action android:name="com.example.reviewbroadcastreciver" /> </intent-filter> </receiver> <receiver android:name=".SecondReceiver"> <!--设置接收广播的优先级--> <intent-filter android:priority="600"> <action android:name="com.example.reviewbroadcastreciver" /> </intent-filter> </receiver> <receiver android:name=".ThirdReceiver"> <!--设置接收广播的优先级--> <intent-filter android:priority="200"> <action android:name="com.example.reviewbroadcastreciver" /> </intent-filter> </receiver> <receiver android:name=".FourthReceiver"> <!--设置接收广播的优先级--> <intent-filter android:priority="0"> <action android:name="com.example.reviewbroadcastreciver" /> </intent-filter> </receiver>
<intent-filter android:priority="1000">配置接收广播的优先级priority的取值从-1000到1000,数值越大优先级越高。
这里只写出第一个广播接收者,其它的代码与之相同。
/** * Created by 春水碧于天 on 2017/1/23. */ public class FirstReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { String msg = getResultData(); Toast.makeText(context,"FirstReceiver"+msg,Toast.LENGTH_SHORT).show(); } }
运行效果:
可以看到每个广播接收者按照清单文件中配置的优先级依次接收
使用setResult修改广播发送的内容:
SecondReceiver.Java
/** * Created by 春水碧于天 on 2017/1/23. */ public class SecondReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { String msg = getResultData(); setResultData("你爸爸叫你回家吃饭啦…………"); Toast.makeText(context,"SecondReceiver"+msg,Toast.LENGTH_SHORT).show(); } }
使用abortBroadcast( )进行广播的截断
ThirdReceiver.Java
/** * Created by 春水碧于天 on 2017/1/23. */ public class ThirdReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { String msg = getResultData(); Toast.makeText(context,"ThirdReceiver"+msg,Toast.LENGTH_SHORT).show(); abortBroadcast(); //进行广播拦截,不再向下传递 } }
运行效果:
可见在 ThirdReceiver 获取的内容为SecondReceiver修改过
的,FourthReceiver因为广播在ThirdReceiver中被截断了,所以没有收到广播,FinalReceiver为最后执行的广播。
┭┮﹏┭┮ O(∩_∩)O
相关文章推荐
- C语言实验——三个整数和、积与平均值
- 浅谈Android MVP模式
- js面向对象编程知识
- js发送集合数据到后台,后台方法参数名用集合接收
- 小鑫の日常系列故事(一)——判断对错 (sdut oj)
- 年度总结
- Python进程/线程/协程相关
- Python学习文章索引
- 第十二节 I/O与正则表达式
- 设计模式学习
- C++ boost 解析 Json
- fmpeg中第三方库的编译_libx264和librtmp
- web端实现表单提交poi导入excel文件
- Tegra TK1安装Opencv1.0
- python3+PyQt5 实现Tab标签页式编辑器
- 简化版ffplay中视频播放逻辑
- 关于C/C++副作用与顺序点的问题
- Netty框架之网络线程模型
- python property方法秒懂
- DevOps在AWS / Azure / Aliyun 的应用分析&对比