android系统休眠发广播,Android - BroadcastReceiver

BroadcastReceiver

BroadcastReceiver,广播接收者,用来接收系统和应用的广播,并做出相应的处理,如电量过低时提示用户充电等;

BroadcastReceiver 是 Android 的四大组件之一,分为 普通广播有序广播粘性广播

BroadcastReceiver 的使用步骤:

自定义一个类,继承自 BroadcastReceiver,并重写 onReceive() 方法,在该方法中对接收到的广播进行相应的处理;

注册广播地址:分为静态注册 (在 AndroidManifest.xml 中注册) 和动态注册 (在代码中注册)

发送广播:普通广播 sendBroadcast()有序广播 sendOrderedBroadcast()粘性广播 sendStickyBroadcast()

自定义广播

普通广播 (Normal Broadcast)

普通广播对于接收者来说是异步的,每个接收者都可以接收到广播,接收者不会相互干扰,也因此,接收者无法终止广播。

1. activity_main:

xmlns:tools="http://schemas.android.com/tools"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:padding="16dp"

tools:context=".MainActivity">

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:text="发送自定义广播"

android:onClick="sendBroadcast"/>

2. MainActivity.java:

public class MainActivity extends AppCompatActivity {

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

}

public void sendBroadcast(View view) {

// 1. 创建一个 Intent 对象;

Intent intent = new Intent();

// 2. 设置 Action;

intent.setAction("net.monkeychan.ACTION_SEND");

// 3. 发送普通广播

sendBroadcast(intent);

}

}

3. MyBroadcastReceiver.java:

// 自定义一个类,继承 BroadcastReceiver 类,并重写 onReceive() 方法

public class MyBroadcastReceiver extends BroadcastReceiver {

@Override

public void onReceive(Context context, Intent intent) {

Log.i("MyBroadcastReceiver", "收到了自定义广播");

}

}

4. 在 AndroidManifest.xml 中注册 (静态注册)

MyBroadcastReceiver:

package="net.monkeychan.broadcastreceivertest01">

android:allowBackup="true"

android:icon="@mipmap/ic_launcher"

android:label="@string/app_name"

android:supportsRtl="true"

android:theme="@style/AppTheme">

5. 效果演示:

d9b150ea90fc

点击按钮,发送广播:

d9b150ea90fc

多次点击,每点击一次就发送一次广播:

d9b150ea90fc

上面的程序是使用静态注册的,下面使用动态注册,布局文件无须作任何修改:

1. MainActivity.java:

public class MainActivity extends AppCompatActivity {

private MyBroadcastReceiver receiver;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

// 1. 创建一个自定义 BroadcastReceiver 的对象;

receiver = new MyBroadcastReceiver();

// 2. 创建一个 IntentFilter 对象,并进行设置

IntentFilter filter = new IntentFilter();

filter.addAction("net.monkeychan.ACTION_SEND");

// 3. 注册广播,该方法需要传入一个 BroadcastReceiver 类型的变量和一个 IntentFilter 类型的变量

registerReceiver(receiver,filter);

}

public void sendBroadcast(View view) {

// 1. 创建一个 Intent 对象;

Intent intent = new Intent();

// 2. 设置 Action;

intent.setAction("net.monkeychan.ACTION_SEND");

// 3. 发送普通广播

sendBroadcast(intent);

}

// 注意:动态注册的 BroadcastReceiver 在 Activity 或 Service 被销毁时必须解除注册

@Override

protected void onDestroy() {

super.onDestroy();

unregisterReceiver(receiver);

}

}

2. 使用动态注册的方式无须再在 AndroidManifest.xml 中注册广播地址:

package="net.monkeychan.broadcastreceivertest01">

android:allowBackup="true"

android:icon="@mipmap/ic_launcher"

android:label="@string/app_name"

android:supportsRtl="true"

android:theme="@style/AppTheme">

3. 效果演示:

d9b150ea90fc

d9b150ea90fc

效果和使用静态注册一样。

静态注册和动态注册的区别

静态注册是在 AndroidManifest.xml 中注册,动态注册是在代码中注册;

静态注册是常驻型的,即使应用没有启动时也能接收广播;而动态注册的广播的生命周期受到其用来注册的 Activity 或 Service 的影响,当其用来注册的 Activity 或 Service 关闭时其广播也就失效了;

动态注册的广播在 Activity 或 Service 被销毁时必须解除注册,而静态注册的关闭则不用;

动态注册的优先级要比静态注册的优先级高。

有序广播 (Ordered Broadcast)

有序广播每次只将广播发送给优先级较高的接收者,优先级高的接收者可以决定是将广播发送给优先级低的接收者,还是终止这个广播。

下面我们自定义三个 BroadcastReceiver,并设置它们的优先级别依次降低,然后发送一条广播,看看效果如何。

1. MainActivity.java:

public class MainActivity extends AppCompatActivity {

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

}

public void sendOrderedBroadcast(View view) {

// 1. 创建一个 Intent 对象,并设置其 Action

Intent intent = new Intent("net.monkeychan.action.OrderedBroadcast");

// 2. 往 Intent 对象里面存放数据

intent.putExtra("money", "我是大当家:给兄弟们每人发十两银子花花。");

// 3. 发送有序广播,该方法需要传入两个参数

/**

* @param intent Intent 对象

* @param receiverPermission 接收者所需要的权限,如果为 null,则接收者无须声明权限即可接收此广播,

* 如果不为 null,则接收者需要在注册时声明此权限才能接收到此广播

*/

sendOrderedBroadcast(intent, "net.monkeychan.permission.OrderedBroadcast");

}

}

2. 主界面布局文件,activity_main:

xmlns:tools="http://schemas.android.com/tools"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:padding="16dp"

tools:context=".MainActivity">

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:text="发送有序广播"

android:onClick="sendOrderedBroadcast"/>

3. 自定义三个 BroadcastReceiver,继承自 BroadcastReceiver:

FirstReceiver.java:

public class FirstReceiver extends BroadcastReceiver {

@Override

public void onReceive(Context context, Intent intent) {

// 取出广播里的数据

String money = intent.getStringExtra("money");

Log.i("Receiver", "FirstReceiver 收到 MainActivity 的消息:" + money);

// 1. 创建一个 Bundle 对象

Bundle bundle = new Bundle();

// 2. 往 Bundle 里存放数据

bundle.putString("money", "我是二当家:大当家说了,给兄弟每人发八两银子花花。");

// 3. 将更改后的数据发送给下一个接收者

setResultExtras(bundle);

}

}

SecondReceiver.java:

public class SecondReceiver extends BroadcastReceiver {

@Override

public void onReceive(Context context, Intent intent) {

// 取出广播里的数据

String money = getResultExtras(true).getString("money");

Log.i("Receiver", "SecondReceiver 收到 FirstReceiver 的消息:" + money);

// 1. 创建一个 Bundle 对象

Bundle bundle = new Bundle();

// 2. 往 Bundle 里存放数据

bundle.putString("money", "我是三当家:大当家说了,给兄弟每人发五两银子花花。");

// 3. 将更改后的数据发送给下一个接收者

setResultExtras(bundle);

}

}

ThirdReceiver.java:

public class ThirdReceiver extends BroadcastReceiver {

@Override

public void onReceive(Context context, Intent intent) {

// 取出广播里的数据

String money = getResultExtras(true).getString("money");

Log.i("Receiver", "ThirdReceiver 收到 SecondReceiver 的消息:" + money);

}

}

4.为三个自定义的 BroadcastReceiver 注册广播地址,并设置它们各自的优先级,AndroidManifest.xml:

package="net.monkeychan.broadcastreceivertest02">

android:allowBackup="true"

android:icon="@mipmap/ic_launcher"

android:label="@string/app_name"

android:supportsRtl="true"

android:theme="@style/AppTheme">

我们在 标签里增加了 android:priority 属性,该属性用于为广播接收者设置优先级,其值范围为 -1000~1000,数值越高优先级越高。

5. 效果演示:

d9b150ea90fc

点击按钮,观察 logcat 日志:

d9b150ea90fc

上面我们说了,优先级高的接收者能够终止当前广播的传播,下面我们对上面的程序修改一下,在 SecondReceiver 终止当前广播的传播:

public class SecondReceiver extends BroadcastReceiver {

@Override

public void onReceive(Context context, Intent intent) {

// 取出广播里的数据

String money = getResultExtras(true).getString("money");

Log.i("Receiver", "SecondReceiver 收到 FirstReceiver 的消息:" + money);

// // 1. 创建一个 Bundle 对象

// Bundle bundle = new Bundle();

// // 2. 往 Bundle 里存放数据

// bundle.putString("money", "我是三当家:大当家说了,给兄弟每人发五两银子花花。");

// // 3. 将更改后的数据发送给下一个接收者

// setResultExtras(bundle);

// 终止当前广播的传播

abortBroadcast();

}

}

效果演示:

d9b150ea90fc

d9b150ea90fc

可以看到,广播在 SecondReceiver 被终止了,优先级比 SecondReceiver 低的接收者无法接收到广播,但同级别的接收者可以接收到。

粘性广播 (Sticky Broadcast)

一般来说,当广播接收者的 onReceive() 方法的执行时间超过 10 秒,系统在资源不足时有可能将其结束掉而不让其执行。但是粘性广播没有这个限制,粘性广播的 Intent 会一直保持到广播结束,没有 10 秒的限制。

下面我们自定义一个 BroadcastReceiver,让其在接收到广播后循环 10 次,每次休眠 5 秒,并在休眠结束之后打印点东西:

1. 主界面布局文件,activity_main.xml:

xmlns:tools="http://schemas.android.com/tools"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:padding="16dp"

tools:context=".MainActivity">

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:text="发送粘性广播"

android:onClick="sendStickyBroadcast"/>

2. 发送广播的代码,MainActivity.java:

public class MainActivity extends AppCompatActivity {

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

}

public void sendStickyBroadcast(View view) {

// 创建一个 Intent 对象,并设置其 Action

Intent intent = new Intent("net.monkeychan.action.STICKYBROADCAST");

sendStickyBroadcast(intent);

}

}

3. 广播接收者,MyBroadcastReceiver.java:

// 自定义一个类,继承 BroadcastReceiver 类,并重写 onReceive() 方法

public class MyBroadcastReceiver extends BroadcastReceiver {

@Override

public void onReceive(Context context, Intent intent) {

// 广播接收者不能执行耗时操作

new Thread(new Runnable() {

@Override

public void run() {

for (int i = 0; i < 5; i++) {

SystemClock.sleep(5 * 1000);

Log.i("MyBroadcastReceiver", "收到了粘性广播" + i);

}

}

}).start();

}

}

4. 注册广播并声明权限,AndroidManifest.xml:

package="net.monkeychan.broadcastreceivertest03">

android:allowBackup="true"

android:icon="@mipmap/ic_launcher"

android:label="@string/app_name"

android:supportsRtl="true"

android:theme="@style/AppTheme">

5. 效果演示:

d9b150ea90fc

点击按钮,注意,这里我们只点击了一次:

d9b150ea90fc

可以看到,当我们点击了一次按钮之后,发送了一个粘性广播,当接收者接收到广播之后,就会执行相应的操作,仔细留意,时间已经超过 10 秒,而广播仍在继续,为了使结果更加富有准确性,可以开多几个程序,使系统开销增大,观察广播超过 10 秒后是否仍在继续。

广播的生命周期

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

广播的安全性

由于 BroadcastReceiver 的设计之初是从全局考虑的,可以方便应用程序和系统、应用程序之间、应用程序内的通信,所以对单个应用程序而难免存在安全方面的问题

,所以,为了避免安全问题,可以从以下几个方面入手:

发送广播时:

发送带权限的广播,在发送广播时指定权限,这样接收者就必须声明对应的权限才能接收到该广播;

指定接收广播的应用包名,Intent.setPackage("com.package.name");

注册广播时:

注册广播时指定权限;

注册广播时使用 androd:exported="false",声明不接收外部应用的广播;

使用本地广播 LocalBroadcastManager,其用于应用内部之间传播,不会泄露给外部应用:

// 1. 获取本地广播管理器对象

LocalBroadcastManager.getInstance(Context context);

// 2. 注册广播

registReceiver(BroadcastReceiver receiver, IntentFilter flter);

// 3. 发送广播

sendBroadcast(Intent); // 发送异步广播

// sendBroadcastSync(Intent intent); // 发送同步广播

// 4. 注销注册

unregisterReceiver(BroadcastReceiver receiver)

参考资料:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/306076.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

开源·共享·创新|2020年中国.NET开发者大会圆满收官!

“疫情无限续费”的2020年&#xff0c;对于14亿中国人而言&#xff0c;是必须习惯口罩长在来脸上的一年&#xff1b;是各种线下聚会&#xff0c;被迫数次延期、滞后、云上举办的一年&#xff1b;……而对于潜心修行&#xff0c;静蓄能量的中国.NET开发者而言&#xff0c;2020绝…

android+百度lbs云,百度——LBS.云 v2.0——云存储扩展字段——Android

今天要解决两个问题&#xff1a;1云存储扩展字段2上传的数据是乱码3android版本上传数据到云端使用了一段时间LBS云功能之后&#xff0c;随着对系统的熟悉&#xff0c;默认提供的字段&#xff0c;肯定无法满足需要。比如增加注释&#xff0c;价格&#xff0c;档次等字段的时候。…

年终将至,回顾我们一起走过的 2020

又到了年终末尾匆匆忙忙的 2020 似乎按下了倍速键一晃眼我们就从夏天走到了冬天在这不平凡的一年中我们同途共进也笑着成长让我们跟随着六大年度词条重温这一年我们共同经历的值得骄傲的瞬间吧&#xff01;点击文内高亮部分&#xff0c;阅读文章了解更多人才“倍”出星桥计划出…

灵魂拷问:你和大佬,技术差距有多大?

今天咱们聊点技术以外的内容。前几天&#xff0c;有程序员在某个坛子上发帖吐槽&#xff0c;新来的应届生张嘴就是分布式&#xff0c;一堆框架&#xff0c;可代码根本不会写。马上有人跟贴说自己也遇到过这种情况&#xff0c;说之前自己遇到过一个应届生&#xff0c;开口闭口动…

达梦数据查询编码_查询数据库的编码方式

在Mysql中(1)查看Mysql数据库编码show variables like character_set_database 或者 show create database 数据库名称(2)查看Mysql中某张表的编码show create table 表名show create database 数据库名称、show create table 表名 &#xff0c;还能够显示建库和建表语句。(3)…

玩转git-flow工作流-分支解析

概述搞开发的相信大部分人git天天都在用&#xff0c;那么一般我们在实际工程当中&#xff0c;遵循一个合理、清晰的Git使用流程&#xff0c;是非常重要的。否则&#xff0c;每个人都提交一堆杂乱无章的commit&#xff0c;项目很快就会变得难以协调和维护。那么是如何来规范整个…

android中的帧动画,[Android开发] Android中的帧动画

MainActivity文件&#xff1a;public class MainActivity extends Activity implements OnClickListener{AnimationDrawable anim_draw;SuppressLint("NewApi")Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);set…

ksu7对讲机调频软件_数字对讲机的群呼功能原理是什么?你了解多少?

大家都明白数字对讲机能够达到组呼、群呼、选呼的用途&#xff0c;但对数字对讲机的群呼功能原理可能操作方并不是太熟悉&#xff0c;下面我们就和大家来谈谈有关数字对讲机的群呼功能原理&#xff1a;无线对讲机群呼是为了更好地达到1个数字对讲机能够同一时间跟多个数字对讲机…

引入Jaeger——使用

上一篇定义了两种使用Jaeger的方式&#xff1a;中间件和action过滤器&#xff0c;下面这个例子定义了两个服务 WebAPI01&#xff0c;请求WebAPI02&#xff0c;采用的是中间件的请求方式。引入JaegerSharp包&#xff08;或发布到自己的Nuget库里引用&#xff09;WebAPI01的Start…

抖音ai智能机器人挂机_电销秘诀 电销企业难以拒绝的AI智能电销机器人

眼下是快节奏的时代&#xff0c;超智能化的电销机器人已然成为了电销企业实现高速发展的首选方式。为何现代电销企业都会摒弃纯人工电销方式&#xff0c;采取机器人与人工协作方式呢&#xff1f;这就不得不说是因为AI外呼机器人的卓越性能和优势。一&#xff0c;提升工作效率AI…

dataset的去重计数 g2_ExcelExcel去重、计数一步到位,这个方法简单到哭

私信回复关键词【插件】&#xff0c;获取Excel高手都在用的“插件合集插件使用小技巧”&#xff01;最近在哼哧哼哧搬家&#xff0c;搬家第一天&#xff0c;面对空荡荡的房子&#xff0c;我发现了一个严峻的问题——日用品还没买。我打开了一个月前写下的日用品清单&#xff1a…

【源码解读】Vue与ASP.NET Core WebAPI的集成

在前面博文【Vue】Vue 与 ASP.NET Core WebAPI 的集成中&#xff0c;介绍了集成原理&#xff1a;在中间件管道中注册SPA终端中间件&#xff0c;整个注册过程中&#xff0c;终端中间件会调用node&#xff0c;执行npm start命令启动vue开发服务器&#xff0c;向中间件管道添加路由…

ios采用什么技术_app软件公司开发宠物别APP采用什么技术?

app软件公司开发宠物别APP采用什么技术&#xff1f;随着经济的发展&#xff0c;人们生活水平的提高&#xff0c;养宠的家庭越来越多&#xff0c;宠物也逐渐成为主人家庭成员的重要组成部分&#xff0c;宠物识别APP在市场上也是很热门的手机软件&#xff0c;那么它是根据什么原理…

Dapr微服务应用开发系列3:服务调用构件块

题记&#xff1a;这篇开始逐一深入介绍各个构件块&#xff0c;从服务调用开始原理所谓服务调用&#xff0c;就是通过这个构件块让你方便的通过HTTP或者gRPC协议同步调用其他服务的方法&#xff0c;这些方法也是通过HTTP或者gRPC来暴露的。而方便的含义在于&#xff0c;你无需担…

Android开发p图软件,媲美大神P图效果 Android软件抠图神手

媲美大神P图效果 Android软件抠图神手2013年02月20日 01:50作者&#xff1a;杨霏霏编辑&#xff1a;杨霏霏文章出处&#xff1a;泡泡网原创分享泡泡网手机频道2月20日 PS的功能大家耳熟能详&#xff0c;其中抠图便是各位PS用户普遍会用到的一个功能。然而手机上抠图大家想过吗&…

腾讯公测云开发低码!实战评测

听说腾讯的新产品『 云开发低码 』即将开放公测了&#xff0c;怀着无比激动的心情&#xff0c;鱼皮立刻去官网申请并成功拿到了公测资格&#xff0c;然后使用它开发了一个小程序&#xff0c;并且通过 2020 Techo Park 开发者大会加深了对这项技术的了解。而就在 2020 年的最后一…

gitee 从 拉取新分支到本地_Hexo博客详细教程(一)| 建立本地站点

点上方蓝字关注我们每天都有好玩的东西等着你博客炫酷效果展示安装Hexo安装Git参考文章&#xff1a;Git实用教程(二) | Git简介及安装详解。安装NodejsNodejs可以从官网( https://nodejs.org/en )下载LTS版本&#xff1a;安装之后检查一下是否正常输出版本信息&#xff1a;安装…

索尼android 怎么截屏快捷键,索尼XZ Premium怎么截屏 2种索尼XZ Premium截图方法

截屏作为手机常用功能之一&#xff0c;我们经常在分享朋友圈或微博的时候经常需要用到屏幕截屏。今天本文主要分享一下索尼XZ Premium怎么截屏&#xff0c;作为一款相对冷门的非国产骁龙835旗舰机&#xff0c;在使用中难免出现一些不太熟悉的问题&#xff0c;下面小编分享2种索…

IdentityServer4 之Client Credentials走起来

前言API裸奔是绝对不允许滴&#xff0c;之前专门针对这块分享了jwt的解决方案(WebApi接口裸奔有风险)&#xff1b;那如果是微服务&#xff0c;又怎么解决呢&#xff1f;每一个服务都加认证授权也可以解决问题&#xff0c;只是显得认证授权这块冗余&#xff0c;重复在搞事情&…

读数据库遇到空就进行不下去_如何保证缓存与数据库的双写一致性?

作者&#xff1a;你是我的海啸来源&#xff1a;https://blog.csdn.net/chang384915878分布式缓存是现在很多分布式应用中必不可少的组件&#xff0c;但是用到了分布式缓存&#xff0c;就可能会涉及到缓存与数据库双存储双写&#xff0c;你只要是双写&#xff0c;就一定会有数据…