安卓广播api介绍,给自己理清楚概念

广播接收器类概述


这是用于接收由sendBroadcast()发送intent的基类。这个类一般都会被继承重写里面的onReceive()方法。。
如果您不需要跨应用程序发送广播,请考虑使用LocalBroadcastManager中的此类,而不是使用下面描述的更通用的工具。这样可以只接受或发送当前应用中的广播。。
您可以使用Context.registerReceiver()动态注册该类的实例,或者通过AndroidManifest.xml中的<.>标记静态发布实现。。
如果在Activity.onResume()实现中注册一个接收器,则应该在Activity.onPause()中注销它。(暂停时不会收到意图,这将减少不必要的系统开销)。

广播主要分为2大类:

关于广播你首先要清楚:广播的传输过程数据传输过程完全异步。 异步的定义为:接收方完全不知道发送方什么时候发送,但发送方一发送,就会提醒接受方接收,至于接受方接不接受,发送方不管了,就去干其他的事了。如果这个过程是同步的话,那么发送方一定会确定接收方接受后才会继续发送,否则就等待。在广播系统中,很显然用异步机制才更合理。
由于异步这个特征,广播可以分为两类:
1.无序广播(正常广播):最纯粹的广播,就是具有以上基本特征的广播。
2.有序广播:在正常广播基础上添加了接收广播优先权的特征。广播一次传递给一个接收器。接收器按优先级priority接收。优先接收到广播的接收器可以中止广播,让广播不在继续往下传递。具有相同优先级的接收器接收广播的顺序随机。
即使在正常广播的情况下,系统在某些情况下也可以恢复成一次只传送给一个接收器。特别的,对于可能需要创建进程的接收器,一次只运行一个,以避免新进程使系统过载。然而,这种情况下,非有序语义保持,这些接收器仍然不能返回结果或中止他们的广播。(这一条在开进程接收广播的情况下要注意的细节,以你的水平,先忽略吧。)
以下这一点,最近才知道,重点标注一下。
尽管intent类用于发送和接收广播,但是这里的intent广播机制与使用Content.startActivity()启动活动的Intent是完成独立的。广播接收器无法查看或捕获与startActivity()一起使用的intent,同样,在发送广播intent时,这个intent也不会被活动给捕获到。这两个操作在语义上非常不同:使用intent启动活动是修改用户当前与之交互内容的前台操作;广播intent是用户通常不知道的背景操作
BroadcastReceiver类当通过清单标记位组件启动时,那它的生命周期就是整个应用程序的生命周期。
主题包括:
1.安全性
与上下文API一起使用的接收者本质上是跨应用程序的工具,因此必须考虑其他应用程序可能如何滥用它们。一些需要考虑的事情是:
(1).意图命名空间是全局的,确保你在自己的意图命名空间中写入了意图操作名称和其他字符串,否则可能会和其他应用程序相冲突。
(2).当你注册了广播接收器时,任何应用程序都可以通过向该接收器发送广播,你可以通过以下方法控制谁可以向你发送广播。
(3)当你在应用程序的清单中发布接收器并为其制定意图过滤器时,任何其它应用程序都可以向其发送广播,而不管你指定的过滤器是什么。也就是说你可以不接受,但你不能阻止别人不发送给你。为了防止其他人发送给你,可以设置exported = false.
(4)当使用sendBroadcast()或相关方法时,通常任何其他应用程序都可以接受这些广播。你可以通过以下权限来控制谁可以接受这样的广播,或者使用intent.setPackage安全地将广播限制到单个应用程序.
当你使用LocalBroadcastManager,上面那些跨程序接受广播的问题都不存在,所以这种广播永远不会在当前进程之外。所以你要学会使用当你使用LocalBroadcastManager。
访问权限可以由广播的发送者或接收者强制执行。

  • 若要在发送时强制执行权限,请向sendBroadcast(Intent,String)或sendOrderedBroadcast(Intent,String,BroadcastReceiver,android.os.Handler,int,String,Bundle)提供非空权限参数。只有被授予此权限的接收者(通过在其AndroidManifest.xml中使用<use-permission>标记请求它)才能够接收广播。
  • 为了在接收时强制执行权限,在注册接收器时提供非空权限——在调用registerReceiver(BroadcastReceiver,IntentFilter,String,android.os.Handler)时或者在AndroidManifest.xml.只有被授予此权限的广播商(通过在其AndroidManifest.xml中使用<use-permission>标记请求它)才能够向接收器发送Intent.

2.接收器生命周期
接收器对象只对调用onReceive()的持续时间有效。一旦你的代码从这个函数返回,系统就认为该对象将被完成并且不再激活。
这对于在onReceive()实现中可以执行的操作有重要的影响任何需要异步操作的操作都不可用。因为需要函数返回来处理异步操作结果,但此时接收器不是较长的活动,因此系统可以自由的在异步操作完成之前完成它的进程。
特别是,你可能不会在广播接收器中显示对话或绑定服务。对于前者,你应该使用NotificationManager(),对于后者,可以使用Context.startService()向服务发送命令。因为你若在广播里绑定服务,那么服务的生命周期就如同广播一样短了。
进程生命周期
当前正在执行BroadcastReceiver(执行onReceive代码)的进程被认为是前台进程,系统将保持运行,除非在极端内存压力的情况下。 一旦从onReceive()返回,BroadcastReceiver就不再是活动的,并且它的宿主进程只与运行在其中的任何其他应用程序组件一样重要。这一点尤其重要,因为该进程仅仅托管BroadcastReceiver,那么当从onReceiver()返回时,系统将认为其进程是空的,并积极的杀死它,从而将资源用于其他更重要的过程。
这意味着,对于长时间的操作,你通常可以将服务和BroadcastReceive结合使用,以便在操作的整个时间保持包含的进程为活动的。例如在服务里频繁的发送广播给接收器,让它保持活动状态.


LocalBroadcastManager

上面提到过这个类,作为在自己应用中发送接受广播,它是你的首选,所以来看看它的描述。
帮助你注册和发送内容到你的进程中的本地对象的广播,相比于发送全球广播有很多优点

你知道你正在播放的数据不会离开你的应用程序,所以不必担心泄露私人数据。
其他应用程序不可能将这些广播发送到您的应用程序,因此您不必担心它们可能利用安全漏洞。
它比通过系统发送全球广播更有效。
这些优点,看了之后就用它了。

总结:理清广播的发送流程很重要,要不然很容易被动态注册、静态注册,有序广播,无序广播这些名词给搞晕。首先,广播的发送者,context.sendBroadcast(intent).通过intent包装数据,这里包括putExtra数据,还有setAction添加intent识别标记。广播接受者(BroadcastReceiver)可以是你写的一个内部类,也可以是一个你单独写的类文件。在onReceive()接受发送时传递的intent,处理数据.最最容易忽视的一点:你重写的这个recevier,一定要注册。要不然它不会与广播产生任何关联。你可以通过在mainfest中注册,也可以在代码中注册。不管哪种方式,一定要有!!!

原文地址:https://www.cnblogs.com/shu94/p/9729424.html