Android学习之基础知识八—Android广播机制

一、广播机制简介

  Android提供了一套完整的API,允许应用程序自由的发送和接受广播,发送广播借助于我们之前学过的:Intent,而接收广播需要借助于广播接收器(Broadcast Receiver)

  广播的类型主要分为两种:标准广播和有序广播。

  标准广播:一种完全异步执行的广播,在广播发出之后,所有接收器几乎在同一时刻接收到这条广播消息,因此它们之间没有任何的先后顺序可言,这种广播的效率会比较高,但是同时也意味着它无法被截断的。标准广播的工作流程图如图所示:

  有序广播:一种同步执行的广播,在广播发出之后,同一时刻只会有一个广播接收器能够接收到这条广播,当这个广播接收器中的逻辑执行完毕后,广播才会继续传递,所以这种广播接收器是有先后顺序的,优先级高的广播接收器就可以先收到广播消息,并且前面的广播接收器还可以截断正在传递的广播,这样后面的广播接收器就无法收到广播消息了。有序广播的工作流程如图所示:

二、接收系统广播

  Android内置了很多的系统级别的广播,我们可以在应用程序中提通过监听这些广播来得到各种系统的状态信息。比如手机开机、电池的电量、时间或时区发生改变等情况下发出一条广播,要接受这些广播,就需要使用广播接收器。

  广播接收器可以自由的对自己感兴趣的广播进行注册,注册广播的方式一般有两种,在代码中注册称为动态注册,在AndroidManifest.xml中注册称为静态注册。

2.1  动态注册监听网络变化

第一步:声明网络权限。Android系统为了保护用户设备的安全和隐私,做了严格的规定:如果程序需要进行一些对用户来说比较敏感的操纵,就必须在配置文件中声明权限才可以,否则程序将会直接崩溃。这里访问的是系统的网络状态,所以需要进行以下权限声明。

第二步:

在MainActivity活动中创建广播接收器,并进行注册

第三步:运行程序,会弹出:network is available的提示(左),接着点击Home键,不要点击Back键,回到主界面后,进入设置,打开手机的飞行模式,会弹出:network is unavailable(右)

     

 2.2  静态注册广播接收器

  动态注册的广播接收器可以自由的控制注册与注销,在灵活性方面有很大的优势,但是它有一个缺点,就是必须要在程序启动之后才能接收到广播,因为注册的逻辑是写在onCreate()方法中的。为了让程序在未启动的情况下就能收到广播,就需要使用到静态注册方式了。

第一步:先创建一个广播接收器BroadCompleteReceiver,New--->Other--->Broadcast Receiver.

  Exported:表示是否允许这个广播接收器接收本程序以外的广播

  Enabled:表示是否启用这个广播接收器。

第二步:在创建的广播接收器中设置一个Toast显示,表示当这个广播接收器接收到消息后弹出一个提示信息。

第三步:在AndroidManifest.xml中对创建的广播接收器添加想要监听的action,并进行权限声明,注意:我们在创建BroadCompleteReceiver广播接收器的时候,系统就已经自动在AndroidManifest.xml中注册了。

  Android系统启动完成后会发出一条值为:android.intent.action.BOOT_COMPLETED  的广播,因此我们在<Intent-filter>标签中添加相应的action。然后使用<user-permission>标签中又添加一条:android.permission.RECEIVE_BOOT_COMPLETED权限。

第四步:关闭模拟器再打开,就会收到一个开机广播

三、发送自定义广播

  前面我们提到广播有两种类型:标准广播和有序广播

3.1  发送标准广播

第一步:创建一个自定义广播接收器,用于接收到广播后执行的操作

第二步:在AndroidManifest.xml中注册:MyReceiver广播接收器(已自动注册),给发送的广播自定义一个值:

<action android:name="com.workspace.hh.broadcasttest.MY_RECEIVER"/>

第三步:在activity_main.xml中设置一个按钮,通过点击按钮来发送自定义的广播

第四步:在MainActivity的:onCreate()方法中为按钮设置监听事件:

  发送广播时,先创建一个Intent对象,把需要发送的广播的值传入,然后调用:context的sendBroadcast()方法,把广播发送出去。这样所有监听:com.workspace.hh.broadcasttest.MY_RECEICER 这条广播的广播接收器就会收到消息。

第五步:运行程序,点击按钮发送广播

3.2  广播跨进程通信

   广播时一种可以跨进程的通信方式,因此我们在应用程序内发出的广播,在其他应用程序也能收到,下面我们就来看一下效果:

第一步:新建一个项目:BroadcastTest2,并自定义一个广播接收器:AnotherBroadcastReceiver,然后在AndroidManifest.xml中添加要监听的广播的值:com.workspace.hh.broadcasttest.MY_RECEIVER

第二步:运行项目BroadcastTest2,然后在BroadcastTest项目程序中点击按钮,可以看到先后弹出来两个提示信息,这说明两个应用程序都接收到了广播

    

3.3  发送有序广播

  发送有序只需要修改一个地方就行了:将:sendBroadcast()改为:sendOrderedBroadcast().

  sendOrderedBroadcast()方法接收两个参数:一个是Intent,另一个是与权限相关的字符串,这里传入null就行了。

  修改这个地方过后,虽然发送的广播已经是有序广播了,但是效果还是与标准广播一样会弹出两个提示信息,下面我们来通过截断广播看效果:

第一步:给:MyReceiver广播接收器设置优先级,使得:MyReceiver比其他广播接收器先接收到广播,在AndroidManifest.xml中通过:android:priority  属性给广播接收器设置优先级

第二步:在MyReceiver广播接收器中截断广播,及后面的接收器就接收不到广播了,在Toast提示信息下面添加:abortBroadcast()方法,该方法表示在此截断广播,后面的广播接收器就再也接收不到该广播了。

第四步:重新运行BroadcastTest和BroadcastTest2这两个程序,然后点击BroadcastTest程序中的按钮,我们看到只有一条提示信息弹出来:received in myReceiver

四、 使用本地广播

  前面我们发送和接收的广播都是属于系统全局广播,即发出的广播可以被其他应用程序接收到,并且我们也可以接收来自于其他应用程序的广播。这样就很容易引起安全性问题,比如说

我们发送的一些携带关键性数据的广播有可能被其他应用程序截获,或者其他应用程序不停的向我们的广播接收器发送各种垃圾广播。

  为了解决广播的安全性问题,Android提供了一套本地的广播机制,使用这个机制发出的广播只能在应用程序的内部传递,并且广播接收器也只能接收来自本应用程序发出的广播,这样所有的安全性问题就不存在了。

第一步:修改MainActivity活动中的代码:

第二步:运行程序,点击按钮,就会弹出:received local Broadcast  的提示信息。如果我们在BroadcastTest2这个应用程序中也去接收这条广播,很明显是接收不到的,因为这条广播只在BroadcastTest程序中传播。

本地广播的注意事项:

  本地广播是无法通过静态注册的方式来接收的,因为静态注册主要是为了让程序在未启动的情况下也能接收到广播,而发送本地广播时,我们的程序肯定是已经启动了,因此完全不需要使用静态注册的功能。

本地广播的几点优势:

  1、可以明确地知道正在发送的广播不会离开我们的应用程序,因此不必担心机密数据泄漏

  2、其他程序无法将广播发送到我们程序的内部,因此不需要担心会有安全漏洞的隐患

  3、发送本地广播比发送系统全局广播将会更加高效

原文地址:https://www.cnblogs.com/hh8888-log/p/10098187.html

时间: 2024-08-04 22:25:19

Android学习之基础知识八—Android广播机制的相关文章

Android学习之基础知识八—Android广播机制实践(实现强制下线功能)

强制下线功能算是比较常见的了,很多的应用程序都具备这个功能,比如你的QQ号在别处登录了,就会将你强制挤下线.实现强制下线功能的思路比较简单,只需要在界面上弹出一个对话框,让用户无法进行任何操作,必须要点击对话框中的确定按钮,然后回到登录界面即可.下面我们就来一步一步的实现这个功能: 第一步:创建一个活动管理器ActivityCollector,用于管理所有的活动 第二步:创建所有活动的父类BaseActivity,继承AppCompatActivity 因为所有的活动都是继承该活动,所有我们在该

Android学习之基础知识十四 — Android特色开发之基于位置的服务

一.基于位置的服务简介 LBS:基于位置的服务.随着移动互联网的兴起,这个技术在最近的几年里十分火爆.其实它本身并不是什么时髦的技术,主要的工作原理就是利用无线电通讯网络或GPS等定位方式来确定出移动设备所在的位置,而这种技术早在很多年前就已经出现了. 那么为什么LBS技术直到最近几年才开始流行呢?这主要是因为,在过去移动设备的功能及其有限,即使定位到了设备所在的位置,也就仅仅只是定位到了而已,我们并不能在位置的基础上进行一些其他的操作.而现在就大大不同了,有了Android系统作为载体,我们可

Android学习之基础知识十六 — Android开发高级技巧的掌握

一.全局获取Context的技巧 前面我们很多地方都使用到了Context,弹出Toast的时候.启动活动的时候.发送广播的时候.操作数据库的时候.使用通知的时候等等.或许目前来说我们并没有为得不到Context而发愁,因为我们很多地方都是在活动中进行的,而活动本身就是一个Context对象,但是,当应用程序的架构逐渐开始复杂起来的时候,很多的逻辑代码都将脱离Activity类,但此时又恰恰需要使用Context,特许这个时候就会感到有些伤脑筋了. 举个例子,在前面网络编程的最佳实践中,我们编写

Android学习之基础知识九 — 数据存储(持久化技术)之使用LitePal操作数据库

上一节学习了使用SQLiteDatabase来操作SQLite数据库的方法,接下来我们开始接触第一个开源库:LitePal.LitePal是一款开源的Android数据库框架,它采用了对象关系映射(ORM)的模式,并将我们平时开发最常用到的一些数据库功能进行了封装,使得不用编写一行SQL语句就可以完成各种建表和增删改查的操作,LitePal的项目主页上也有详细的使用文档,地址是: https://github.com/LitePalFramework/LitePal 一.配置LitePal 要在

Android学习之基础知识二(build.gradle文件详解)

一.详解build.gradle文件 1.Android Studio是采用Gradle来创建项目的,Gradle是非常先进的构建的项目的工具,基于Groovy领域特定的语言(DSL)来声明项目配置,摒弃了传统基于XML(如Ant.Maven)的各种烦琐的配置. 2.Android项目中存在两个build.gradle文件,一个在外层,一个在app中: A.外层的build.gradle文件:当需要添加全局的项目构建配置时才修改其中的内容 jcenter():代码托管仓库,存放Android开源

Android学习之基础知识七—碎片的使用

碎片(Fragment)是一种可以嵌入在活动中的UI片断,它能让程序更加合理和充分地利用大屏幕的空间,它与活动相似,可以简单的理解为一个迷你型的活动,它也有自己的生命周期.碎片在平板的应用非常广泛. 一.碎片的简单用法 需求:在一个活动中添加两个碎片,并让这两个碎片平分活动空间. 第一步:由于碎片通常应用在平板开发中,所以先创建一个平板模拟器,然后新建一个Android项目:FragmentTest 第二步:创建左侧.右侧两个碎片布局     第三步:新建一个LeftFragment类继承Fra

Android学习之基础知识十三—网络编程的最佳实践

上一讲已经掌握了HttpURLConnection和OkHttp的用法,知道如何发起HTTP请求,以及解析服务器返回的数据,但是也许你还没发现,之前我们的写法其实是很有问题的,因为一个应用程序很可能会在许多地方使用到网络功能,而发送HTTP请求的代码基本都是相同的,如果我们每次都去编写一遍发送HTTP请求的代码,这显然是非常差劲的做法. 通常情况下我们都应该将这些通用的网络操作提取到一个公共的类里,并提供一个静态方法,当想要发起网络请求的时候,只需要简单的调用一下这个方法即可,比如使用如下的写法

Android学习笔记(十八)——使用意图筛选器和实现浏览网页(附源码)

使用意图筛选器 点击下载源码 1.创建一个Intents项目,给该项目添加一个新类,命名为MyBrowserActivity,在res/layout文件夹下新增一个browser.xml: 2.在AndroidManifest.xml文件中添加如下代码: 添加权限: <uses-permission android:name="android.permission.CALL_PHONE" /> <uses-permission android:name="a

Android学习路线(十八)支持不同设备——支持不同的屏幕

Android系统使用两个普通属性:尺寸和密度,来对设备屏幕进行分类.你需要先预测你的应用将会在什么样屏幕的设备上安装,包括屏幕尺寸和密度.这样的话,你就需要提供一些可选的资源类让你的应用在不同屏幕的设备上有最佳的展示. 有四种普遍的尺寸:small, normal, large, xlarge 还有四种普遍的密度:low (ldpi), medium (mdpi), high (hdpi), extra high (xhdpi) 要为不同的屏幕声明不同的布局和图片,你需要让这些可选的资源放在不