android广播的作用-金沙1005

android广播的作用_android广播原理broadcastreceiver也就是“广播接收者”的意思,顾名思义,它就是用来接收来自系统和应用中的广播。在android系统中,广播体现在方方面面,例如当开机完成后系统会产生一条广播,接收到这条广播就能实现开机启动服务的功能;当网络状态改变时系统会产生一条广播,接收到这条广播就能及时地做出提示和保存数据等操作;当电池电量改变时,系统会产生一条广播,接收到这条广播就能在电量低时告知用户及时保存…

broadcastreceiver也就是“广播接收者”的意思,顾名思义,它就是用来接收来自系统和应用中的广播。

在android系统中,广播体现在方方面面,例如当开机完成后系统会产生一条广播,接收到这条广播就能实现开机启动服务的功能;当网络状态改变时系统会产生一条广播,接收到这条广播就能及时地做出提示和保存数据等操作;当电池电量改变时,系统会产生一条广播,接收到这条广播就能在电量低时告知用户及时保存进度,等等。

android中的广播机制设计的非常出色,很多事情原本需要开发者亲自操作的,现在只需等待广播告知自己就可以了,大大减少了开发的工作量和开发周期。而作为应用开发者,就需要数练掌握android系统提供的一个开发利器,那就是broadcastreceiver。下面我们就对broadcastreceiver逐一地分析和演练,了解和掌握它的各种功能和用法。

首先,我们来演示一下创建一个broadcastreceiver,并让这个broadcastreceiver能够根据我们的需要来运行。要创建自己的broadcastreceiver对象,我们需要继承android.content.broadcastreceiver,并实现其onreceive方法。下面我们就创建一个名为myreceiver广播接收者:

public class myreceiver extends broadcastreceiver {

private static final string tag = “myreceiver”;

@override

public void onreceive(context context, intent intent) {

string msg = intent.getstringextra(“msg”);

log.i(tag, msg);

}

}

在onreceive方法内,我们可以获取随广播而来的intent中的数据,这非常重要,就像无线电一样,包含很多有用的信息。

在创建完我们的broadcastreceiver之后,还不能够使它进入工作状态,我们需要为它注册一个指定的广播地址。没有注册广播地址的broadcastreceiver就像一个缺少选台按钮的收音机,虽然功能俱备,但也无法收到电台的信号。下面我们就来介绍一下如何为broadcastreceiver注册广播地址。

broadcastreceiver的注册方式分为两种:

1.静态注册

静态注册是在androidmanifest.xml文件中配置的,我们就来为myreceiver注册一个广播地址:

配置了以上信息之后,只要是android.intent.action.my_broadcast这个地址的广播,myreceiver都能够接收的到。注意,这种方式的注册是常驻型的,也就是说当应用关闭后,如果有广播信息传来,myreceiver也会被系统调用而自动运行。

2.动态注册

动态注册需要在代码中动态的指定广播地址并注册,通常我们是在activity或service注册一个广播,下面我们就来看一下注册的代码:

myreceiver receiver = new myreceiver();

intentfilter filter = new intentfilter();

filter.addaction(“android.intent.action.my_broadcast”);

registerreceiver(receiver, filter);

注意,registerreceiver是android.content.contextwrapper类中的方法,activity和service都继承了contextwrapper,所以可以直接调用。在实际应用中,我们在activity或service中注册了一个broadcastreceiver,当这个activity或service被销毁时如果没有解除注册,系统会报一个异常,提示我们是否忘记解除注册了。所以,记得在特定的地方执行解除注册操作:

@override

protected void ondestroy() {

super.ondestroy();

unregisterreceiver(receiver);

}

执行这样行代码就可以解决问题了。注意,这种注册方式与静态注册相反,不是常驻型的,也就是说广播会跟随程序的生命周期。

我们可以根据以上任意一种方法完成注册,当注册完成之后,这个接收者就可以正常工作了。我们可以用以下方式向其发送一条广播:

public void send(view view) {

intent intent = new intent(“android.intent.action.my_broadcast”);

intent.putextra(“msg”, “hello receiver.”);

sendbroadcast(intent);

}

注意,sendbroadcast也是android.content.contextwrapper类中的方法,它可以将一个指定地址和参数信息的intent对象以广播的形式发送出去。

上面的例子只是一个接收者来接收广播,如果有多个接收者都注册了相同的广播地址,又会是什么情况呢,能同时接收到同一条广播吗,相互之间会不会有干扰呢?这就涉及到普通广播和有序广播的概念了。

1.普通广播(无序广播)

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

为了验证以上论断,我们新建三个broadcastreceiver,演示一下这个过程,firstreceiver、secondreceiver和thirdreceiver的代码如下:

public class firstreceiver extends broadcastreceiver {

private static final string tag = “normalbroadcast”;

@override

public void onreceive(context context, intent intent) {

string msg = intent.getstringextra(“msg”);

log.i(tag, “firstreceiver: ” msg);

}

}

public class secondreceiver extends broadcastreceiver {

private static final string tag = “normalbroadcast”;

@override

public void onreceive(context context, intent intent) {

string msg = intent.getstringextra(“msg”);

log.i(tag, “secondreceiver: ” msg);

}

}

public class thirdreceiver extends broadcastreceiver {

private static final string tag = “normalbroadcast”;

@override

public void onreceive(context context, intent intent) {

string msg = intent.getstringextra(“msg”);

log.i(tag, “thirdreceiver: ” msg);

}

}

然后再次点击发送按钮,发送一条广播,控制台打印如下:

b37e22bd66a9

0_13209098830cao.gif

看来这三个接收者都接收到这条广播了,我们稍微修改一下三个接收者,在onreceive方法的最后一行添加以下代码,试图终止广播:

abortbroadcast();

2.有序广播

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

为了演示有序广播的流程,我们修改一下上面三个接收者的代码,如下:

public class firstreceiver extends broadcastreceiver {

private static final string tag = “orderedbroadcast”;

@override

public void onreceive(context context, intent intent) {

string msg = intent.getstringextra(“msg”);

log.i(tag, “firstreceiver: ” msg);

bundle bundle = new bundle();

bundle.putstring(“msg”, msg “@firstreceiver”);

setresultextras(bundle);

}

}

public class secondreceiver extends broadcastreceiver {

private static final string tag = “orderedbroadcast”;

@override

public void onreceive(context context, intent intent) {

string msg = getresultextras(true).getstring(“msg”);

log.i(tag, “secondreceiver: ” msg);

bundle bundle = new bundle();

bundle.putstring(“msg”, msg “@secondreceiver”);

setresultextras(bundle);

}

}

public class thirdreceiver extends broadcastreceiver {

private static final string tag = “orderedbroadcast”;

@override

public void onreceive(context context, intent intent) {

string msg = getresultextras(true).getstring(“msg”);

log.i(tag, “thirdreceiver: ” msg);

}

}

我们注意到,在firstreceiver和secondreceiver中最后都使用了setresultextras方法将一个bundle对象设置为结果集对象,传递到下一个接收者那里,这样以来,优先级低的接收者可以用getresultextras获取到最新的经过处理的信息集合。

代码改完之后,我们需要为三个接收者注册广播地址,我们修改一下androidmainfest.xml文件:

我们看到,现在这三个接收者的多了一个android:priority属性,并且依次减小。这个属性的范围在-1000到1000,数值越大,优先级越高。

现在,我们需要修改一下发送广播的代码,如下:

public void send(view view) {

intent intent = new intent(“android.intent.action.my_broadcast”);

intent.putextra(“msg”, “hello receiver.”);

sendorderedbroadcast(intent, “scott.permission.my_broadcast_permission”);

}

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

所以我们在androidmainfest.xml中定义一个权限:

android:name=”scott.permission.my_broadcast_permission” />

然后声明使用了此权限:

然后我们点击发送按钮发送一条广播,控制台打印如下:

b37e22bd66a9

0_1320913997fkkj.gif

我们看到接收是按照顺序的,第一个和第二个都在结果集中加入了自己的标记,并且向优先级低的接收者传递下去。

既然是顺序传递,试着终止这种传递,看一看效果如何,我们修改firstreceiver的代码,在onreceive的最后一行添加以下代码:

abortbroadcast();

然后再次运行程序,控制台打印如下:

b37e22bd66a9

0_1320914377loyl.gif

3.粘性广播

发送粘性广播使用sendstickybroadcast()字面意思是发送粘性的广播,使用这个api需要权限android.manifest.permission.broadcast_sticky,粘性广播的特点是intent会一直保留到广播事件结束,而这种广播也没有所谓的10秒限制,10秒限制是指普通的广播如果onreceive方法执行时间太长,超过10秒的时候系统会将这个广播置为可以干掉的candidate,一旦系统资源不够的时候,就会干掉这个广播而让它不执行。

4.本地广播

本地广播是在应用进程内进行的广播,相对于普通广播有如下优点:

1.效率比普通广播高,普通广播是依靠binder实现的,本地广播是handler实现的。

2.比普通广播安全,普通广播全局都可以接受,本地广播只有应用进程内才可以接收到。

下面是本地广播的实现:

public class mainactivity extends actionbaractivity {

private button button;

private textview text;

private myreceiver receiver;

private intentfilter filter;

private context context;

private static final string my_broadcast_tag = “com.example.localbroadcasttest”;

@override

protected void oncreate(bundle savedinstancestate) {

super.oncreate(savedinstancestate);

setcontentview(r.layout.activity_main);

context = getapplicationcontext();

receiver = new myreceiver();

filter = new intentfilter();

filter.addaction(my_broadcast_tag);

button = (button) findviewbyid(r.id.button);

text = (textview) findviewbyid(r.id.text);

button.setonclicklistener(new view.onclicklistener() {

@override

public void onclick(view view) {

intent intent = new intent();

intent.setaction(my_broadcast_tag);

intent.putextra(“message”, “hello~”);

localbroadcastmanager.getinstance(context).sendbroadcast(intent);

}

});

}

@override

protected void onresume() {

super.onresume();

localbroadcastmanager.getinstance(context).registerreceiver(receiver, filter);

}

@override

protected void onpause() {

super.onpause();

localbroadcastmanager.getinstance(context).unregisterreceiver(receiver);

}

class myreceiver extends broadcastreceiver {

@override

public void onreceive(context arg0, intent arg1) {

string message = arg1.getstringextra(“message”);

text.settext(“接受到广播:\ntext = ” message);

}

}

}

在最后在说一下广播接受者的生命周期以及一下细节部分:

1.广播接收者的生命周期是非常短暂的,在接收到广播的时候创建,onreceive()方法结束之后销毁。

2.广播接收者中不要做一些耗时的工作,否则会弹出application no response错误对话框。

3.最好也不要在广播接收者中创建子线程做耗时的工作,因为广播接收者被销毁后进程就成为了空进程,很容易被系统杀掉。

4.耗时的较长的工作最好放在服务中完成。

js555888金沙老品牌的版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由思创斯整理,转载请注明出处:https://ispacesoft.com/141160.html

(0)

相关推荐

  • the android sdk location cannot_copy path在运行的时候出现这个错误,版本的要求不一样点上对勾,直接apply就可以了

  • android toast 显示在最上面,android toast在屏幕上移动我的android应用程序显示多个toast消息.我最近将它安装在运行android5.1.1的galaxys6上,并注意到消息最初显示在屏幕中央,然后移动到正确的位置(如果没有指定gravity,则在底部附近),然后返回到初步离职前的位置.contextcontext=getapplicationcontext();stringnewmsg=getstring(r.string….

  • android-5_android模块化由于android5.1user版本的selinux安全机制的限制,导致pppd_gprs服务起不来,4g信号出现叹号上不了网。出现:init:sys_prop:unabletostartservicectl[pppd_gprs]uid:1001gid:1001pid:187原因:这是因为android5.1在selinux的基础上增加了对property的权限的限制解决1…

  • android播放器自定义,我的音乐我做主 最强自定义android播放器「建议收藏」对于android用户来说,launcherpro的知名度非常高,这款自定义桌面曾是第三方桌面的首选,现在launcherpro团队又推出了一款全新的音乐播放器ubermusic。ubermusic是一款非常漂亮的并可以高度定制的android音乐播放器,这款播放器目前在官方电子市场售价为3.5美元,支持android2.0 设备。你可以通过安装不同的皮肤来调整整个用户界面,使用wp7风格皮肤时…

  • 调用android自带浏览器打开网页[通俗易懂]在android中可以调用自带的浏览器,或者指定一个浏览器来打开一个链接。只需要传入一个uri,可以是链接地址。启动android默认浏览器在android程序中我们可以通过发送隐式intent来启动系统默认的浏览器。如果手机本身安装了多个浏览器而又没有设置默认浏览器的话,系统将让用户选择使用哪个浏览器来打开连接。uriuri=uri.parse(“https://www.baidu.com”

  • 安卓mediaplayer使用_手机音频输出设备怎么关闭当我们使用如下代码去实现静音播放的时:mediaplayer.setaudiostreamtype(audiomanager.stream_music);mediaplayer.setvolume(0,0);当我们接听电话返回后,会发现静音失效,原本静音播放的视频有声音了!解决这个问题的办法是设置:mmediaplayer.setaudiostreamtype(audiom…

  • android 图片资源_android预加载布局下图是一个客户端图片加载模块常见的处理流程。imagepipeline.png本文以universalimageloader为例分析了这一流程,然后分析了fresco的优势和问题,最终推荐大家使用glide。从universalimageloader分析图片加载中需要处理的问题网络主要用于下载网络图片,在uil中是将图片地址变为inputstream。uil支持多种类型来源的图片显示,包括:网络文…

  • reactnative打包apk_react native 0.65android打release包(androidstudio环境)1.生成静态jsbundle文件1.1:首先在本地修改assetpathutils.jsassetpathutils.js文件路径:node_modules\react-native\local-cli\bundle\assetpathutils.js修改:getandroidassetsuffix方法因为gr…

    2022年12月26日

发表回复

您的电子邮箱地址不会被公开。

联系金沙1005

关注“java架构师必看”公众号

回复4,添加站长微信。

附言:ispacesoft.com网而来。

关注微信
网站地图