Android学习笔记:广播(Broadcast)

一、分类

BroadcastReceiver是一种全局监听器,用来实现系统中不同组件之间的通信。有时候也会用来作为传输少量而且发送频率低的数据,但是如果数据的发送频率比较高或者数量比较大就不建议用广播接收者来接收了,因为这样的效率很不好,因为BroadcastReceiver接收数据的开销还是比较大的。

  • 标准广播(无序广播/异步)
    ①是一种完全异步执行的广播,在广播发出后,所有的广播接收器几乎都会在同一时刻接收到这条广播消息,因此它们之间没有任何先后顺序。
    ②无序广播不可以被拦截,若被拦截,则会报错。
    ③无序广播的广播接收者之间不能相互传递数据。

  • 有序广播(同步)
    ①是一种同步执行的广播,在广播发出后,同一时刻只会有一个广播接收器能够收到这条广播消息,当这个广播接收器中的逻辑执行完毕后,广播才会继续传递。
    ②优先级高的接收器可截断广播。
    ③在相同优先级下,广播接收者接收的顺序要看接收者在清单文件中声明的顺序,先声明的接收者比后声明的接收者要先接收到广播。
    ④有序广播的广播接收者之间可以互相传递数据。

  • 粘性广播
    ①sendStickyBroadcast()来发送该类型的广播信息。
    ②这种的广播的最大特点是,当粘性广播发送后,最后的一个粘性广播会滞留在操作系统中。如果在粘性广播发送后的一段时间里,如果有新的符合广播的动态注册的广播接收者注册,将会收到这个广播消息,虽然这个广播是在广播接收者注册之前发送的。
    ③对于静态注册的广播接收者来说,这个等同于标准广播。

二、注册广播

注册广播的方式一般有两种,一种是在代码中注册,另一种是在AndroidManifest.xml中注册,前者称为动态注册,后者称为静态注册。

  • 动态注册:必须要在程序启动之后才能接收到广播
    ① 新建一个类,并使其继承自BroadcastReceiver,并重写父类的onReceive()方法就可以创建一个广播接收器。有广播到来时,onReceive()方法就会得到执行,具体的逻辑就可以在该方法在处理。
    ②需要注意的是,动态注册的广播接收器一定都要取消注册才行,可以在onDestroy()方法中调用unregisterReceiver()方法来实现。
    ③动态注册的广播接收器可以自由地控制注册与销毁,在灵活性方面有很大的优势,但是它也存在着一个缺点,即必须要在程序启动之后才能接收广播,因为注册的逻辑是写在onCreate()方法中的。
    通过这种方式注册的广播接收者,只有在代码运行时,广播接收者才生效。若代码运行结束,则广播接收者也失效

  • 静态注册:让程序在未启动的情况下就能接收到广播
    ①包名右击→New→Other→Broadcast Receiver,创建广播接收器。
    ②静态的广播接收器一定要在AndroidManifest.xml文件中注册才可以使用,如果是使用Android Studio的快捷方式①创建的广播接收器,那么这一步会自动完成。
    通过该方式注册的广播接收者在系统中运行一次后就会被注册到系统中,以后无程序运行该应用程序也可以接收到广播

注:
(1)BroadcastReceiver组件可以用来实现低耦合的观察者模式,观察者和被观察者之间可以没有任何耦合。
(2)由于BoardcastReceiver的特性,它不适合用来执行耗时的操作。

三、发送广播

  • 发送标准广播:接收无序广播的接收器收到广播的顺序也是有序的,接收无序广播一样可以设置优先级。如果同优先级的静态接收器想先接收某个广播,就要在包名上修改让它在系统的包名清单中靠前显示。
    sendBroadcast(intent);
    
  • 发送有序广播:获得广播优先权的广播接收器可以选择是否允许广播继续传递。
    //onCreate()方法
    //第一个参数是Intent,第二个参数是与权限相关的字符串
    sendOrderedBroadcast(intent, null);
    
    //onReceive()方法
    //将这条广播截断,后面的广播接收器无法再接收到这条广播
    abortBroadcast();
    

四、本地广播

①只能够在应用程序内部进行传递的广播,并且广播接收器也只能接收来自本应用程序发出的广播,能够简单的解决广播的安全性问题。

②本地广播主要是使用一个LocalBroadcastManager来对广播进行管理,并提供了发送广播和注册广播接收器的方法。

③本地广播是无法通过静态注册(即让程序在未启动的情况下就能接收到广播)的方式来接收的。

五、强制下线

//这条广播用于通知程序强制用户下线的
Intent intent =  new Intent("com.example.broadcastdemo.FOrCE_OFFLINE");
sendBroadcast(intent);

①强制下线的逻辑并不是写在MainActivity里,而是应该写在接收这条广播的接收器里,这样强制下线的功能就不会依附于任何界面,不管在程序任何地方,只需要发出这样一条广播,就可以完成强制下线操作。

②由于广播接收器里面需要一个对话框来阻塞用户的正常操作,但如果创建的是一个静态注册的广播接收器,是没有办法在OnReceive()方法里弹出对话框这样的UI控件的,因此我们可以在BaseActivity中动态的注册一个广播接收器,因为所有的活动都继承自BaseActivity。

六、本地广播与全局广播的区别

引入本地广播的机制是为了解决安全性的问题:
(1)正在发送的广播不会脱离应用程序,不用担心app的数据泄露;
(2)其他的程序无法发送到我的应用程序内部,不担心安全漏洞。(比如:如何做一个杀不死的服务—监听我的app,比如微信、友盟、极光的广播,来启动自己。)
(3)发送本地广播比发送全局的广播高效。(全局广播要维护的广播集合表,效率更低。此外,全局广播,意味着可以跨进程,就需要底层的支持。)
注:本地广播不能用静态注册。(静态注册:可以做到程序停止后还能监听。)

七、广播的使用方式和场景

(1)App全局监听:在AndroidManifest中静态注册的广播接收器,一般我们在收到该消息后,需要做一些相应的动作,而这些动作与当前App的组件,比如Activity或者Service的是否运行无关,比如我们在集成第三方Push SDK时,一般都会添加一个静态注册的BroadcastReceiver来监听Push消息,当有Push消息过来时,会在后台做一些网络请求或者发送通知等等。

(2)组件局部监听:这种主要是在Activity或者Service中使用registerReceiver()动态注册的广播接收器,因为当我们收到一些特定的消息,比如网络连接发生变化时,我们可能需要在当前Activity页面给用户一些UI上的提示,或者将Service中的网络请求任务暂停。所以这种动态注册的广播接收器适合特定组件的特定消息处理。

你可能感兴趣的:(Android,Android,Android学习笔记)