博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android之BroadcastReceiver总结
阅读量:6226 次
发布时间:2019-06-21

本文共 3322 字,大约阅读时间需要 11 分钟。

什么是BroadcastReceiver?

BroadcastReceiver,广播接收者,它是一个系统全局的监听器,用于监听系统全局的Broadcast消息,所以它可以很方便的进行系统组件之间的通信。

BroadcastReceiver属于系统级的监听器,它拥有自己的进程,只要存在与之匹配的Broadcast被以Intent的形式发送出来,BroadcastReceiver就会被激活。

虽然同属Android的四大组件,BroadcastReceiver也有自己独立的声明周期,但是和Activity、Service又不同。当在系统注册一个BroadcastReceiver之后,每次系统以一个Intent的形式发布Broadcast的时候,系统都会创建与之对应的BroadcastReceiver广播接收者实例,并自动触发它的onReceive()方法,当onReceive()方法被执行完成之后,BroadcastReceiver的实例就会被销毁。虽然它独自享用一个单独的进程,但也不是没有限制的,如果BroadcastReceiver.onReceive()方法不能在10秒内执行完成,Android系统就会认为该BroadcastReceiver对象无响应,然后弹出ANR(Application No Response)对话框,所以不要在BroadcastReceiver.onReceive()方法内执行一些耗时的操作。

如果需要根据广播内容完成一些耗时的操作,一般考虑通过Intent启动一个Service来完成该操作,而不应该在BroadcastReceiver中开启一个新线程完成耗时的操作,因为BroadcastReceiver本身的生命周期很短,可能出现的情况是子线程还没有结束,BroadcastReceiver就已经退出的情况,而如果BroadcastReceiver所在的进程结束了,该线程就会被标记为一个空线程,根据Android的内存管理策略,在系统内存紧张的时候,会按照优先级,结束优先级低的线程,而空线程无异是优先级最低的,这样就可能导致BroadcastReceiver启动的子线程不能执行完成。

BroadcastReceiver的种类

  • sendBroadcast():发送普通广播。
  • sendOrderedBroadcast():发送有序广播。

如何使用BroadcastReceiver

清单文件进行注册

复制代码

HelloBroadcastReceiver

public class HelloBroadcastReceiver extends BroadcastReceiver {      @Override      public void onReceive(Context context, Intent intent) {          // 判断当前接收到的Broadcast的action          Log.d("wxl", "intent.getAction()====" + intent.getAction());          if (intent.getAction().equals("com.cl.apksample.HelloBroadcastReceiver")) {              Toast.makeText(context, "接收到Broadcast消息为:" + intent.getStringExtra("msg"), Toast.LENGTH_SHORT).show();          }      }  }  复制代码

发送Broadcast

Intent broadcast = new Intent();                  broadcast.setAction("com.cl.apksample.HelloBroadcastReceiver");         sendBroadcast(broadcast);复制代码

注意:

Android中的广播分为两种类型,标准广播和有序广播标准广播标准广播是一种完全异步执行的广播,在广播发出后所有的广播接收器会在同一时间接收到这条广播,之间没有先后顺序,效率比较高,且无法被截断。有序广播有序广播是一种同步执行的广播,在广播发出后同一时刻只有一个广播接收器能够接收到, 优先级高的(数值越大优先级越高)广播接收器会优先接收,当优先级高的广播接收器的 onReceiver() 方法运行结束后,广播才会继续传递,且前面的广播接收器可以选择截断广播,这样后面的广播接收器就无法接收到这条广播了复制代码
1,该广播的级别有级别之分,级别数值是在-1000到1000之间,值越大,优先级越高;  2,同级别接收是先后是随机的,再到级别低的收到广播;  3,同级别接收是先后是随机的,如果先接收到的把广播截断了,同级别的例外的接收者是无法收到该广播的。(abortBroadcast())  4,能截断广播的继续传播,高级别的广播收到该广播后,可以决定把该钟广播是否截断掉。  5,实验现象,在这个方法发来的广播中,代码注册方式中,收到广播先后次序为:注明优先级的、代码注册的、没有优先级的;如果都没有优先级,代码注册收到为最先。复制代码
  • 动态广播最好在Activity的onResume()注册、onPause()注销。

    原因:对于动态广播,有注册就必然得有注销,否则会导致内存泄露

重复注册、重复注销也不允许复制代码

Activity生命周期如下:

Activity生命周期 Activity生命周期的方法是成对出现的:

  • onCreate() & onDestory()
  • onStart() & onStop()
  • onResume() & onPause()

在onResume()注册、onPause()注销是因为onPause()在App死亡前一定会被执行,从而保证广播在App死亡前一定会被注销,从而防止内存泄露。

1 不在onCreate() & onDestory() 或 onStart() & onStop()注册、注销是因为:当系统因为内存不足(优先级更高的应用需要内存,请看上图红框)要回收Activity占用的资源时,Activity在执行完onPause()方法后就会被销毁,有些生命周期方法onStop(),onDestory()就不会执行。当再回到此Activity时,是从onCreate方法开始执行。2 假设我们将广播的注销放在onStop(),onDestory()方法里的话,有可能在Activity被销毁后还未执行onStop(),onDestory()方法,即广播仍还未注销,从而导致内存泄露。3 但是,onPause()一定会被执行,从而保证了广播在App死亡前一定会被注销,从而防止内存泄露。复制代码

两种注册方式的区别

广播的类型主要分为5类:

  • 普通广播(Normal Broadcast)
  • 系统广播(System Broadcast)
  • 有序广播(Ordered Broadcast)
  • 粘性广播(Sticky Broadcast)
  • App应用内广播(Local Broadcast)

LocalBroadcastManager

之前发送和接收到的广播全都是属于系统全局广播,即发出的广播可以被其他应用接收到,而且也可以接收到其他应用发送出的广播,这样可能会有不安全因素

因此,在某些情况下可以采用本地广播机制,使用这个机制发出的广播只能在应用内部进行传递,而且广播接收器也只能接收本应用内自身发出的广播

需要注意的是,本地广播是无法通过静态注册的方式来接收的,因为静态注册广播主要是为了在程序未启动的情况下也能接收广播,而本地广播是应用自己发送的,此时应用肯定是启动的了。

使用私有权限

参考:

转载地址:http://lmfna.baihongyu.com/

你可能感兴趣的文章
阿里的面试官都喜欢问哪些技术问题?
查看>>
基于curl 的zabbix API调用
查看>>
data guard 的部署
查看>>
oracle hints的那点事
查看>>
U盘拒绝访问怎么办?
查看>>
多网卡team,聚合连接(链路聚合)
查看>>
sublime text 3解放鼠标的快捷键总结
查看>>
我的友情链接
查看>>
Nessus HomeFeed 无法申请注册码解决办法
查看>>
python的第一个脚本
查看>>
mininet和floodlight搭建openflow系统
查看>>
Webkit内核的浏览器中用CSS3+jQuery实现iphone滑动解锁效果(译)
查看>>
常与同好争高下:互联网创业的8条忠告
查看>>
我的友情链接
查看>>
用脚本检测局域网络是否可以ping通
查看>>
jmeter安装
查看>>
我的友情链接
查看>>
HTTP响应代码(Response Status Code)中文详解
查看>>
bootstrap-按钮的向下向上三角形-向上弹起的下拉菜单
查看>>
SQL Server 2017 AlwaysOn AG 自动初始化(四)
查看>>