Android_四大组件之BroadcastReceiver
一、概述
BroadcastReceiver是广播接收器,接收来自 系统或应用发出的广播信息 并进行相应的逻辑处理。
自定义BroadcastReceiver只需继承android.content.BroadcastReceiver,并重写onReceive()方法就可以了。
public class StaticBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
//TODO
}
}
二、基本用法
1.BroadcastReceiver注册:
BroadcastReceiver有两种注册方法,静态注册和动态注册,下面分别说明。
(1)静态注册
在AndroidManifest.xml中通过<receiver>标签 注册的广播,即是静态注册。 静态注册后的广播,在系统启动后,就一直常驻系统内存中,接收符合的广播信息,不管应用是否处于运行状态。
所以它的优点是常驻系统,时刻运行,不受应用及其他组件生命周期的影响;缺点是常驻内存 耗电。比较适合实时监听的场景。
/*
android:exported与其他组件的属性意义相同,如果这里为false,则不接受其他组件的广播,只接收本地应用的广播
*/
<receiver android:name=".StaticBroadcastReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="com.flx.testBroadcastReceiver.TEST_BROADCAST_RECEIVER"></action>
</intent-filter>
</receiver>
注册静态广播的广播接收类。
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log; public class StaticBroadcastReceiver extends BroadcastReceiver {
final private static String TAG = "StaticBroadcastReceiver";
@Override
public void onReceive(Context context, Intent intent) {
Log.d(TAG, "onReceive: "+intent.getStringExtra("testkey"));
}
}
发送广播:
Button sendBroadcastBtn = findViewById(R.id.send_broadcast_btn);
sendBroadcastBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d("StaticBroadcastReceiver", "click");
Intent broadcastIntent = new Intent();
broadcastIntent.setAction("com.flx.testBroadcastReceiver.TEST_BROADCAST_RECEIVER");
broadcastIntent.putExtra("testkey", "testval");
sendBroadcast(broadcastIntent);
}
});
但是 通过log 发现接收器StaticBroadcastReceiver 并没有接收到广播,这是怎么回事呢?看log,报错如下:
2019-07-31 03:17:50.978 883-922/system_process W/BroadcastQueue: Background execution not allowed: receiving Intent
{ act=com.flx.testBroadcastReceiver.TEST_BROADCAST_RECEIVER flg=0x10 (has extras) } to com.flx.testBroadcastReceiver/.StaticBroadcastReceiver
因为是在P上调试的,O以后系统对隐式广播(没有指明接收广播的组件的)做了限制,所以无法接收。 网上有一些关于如何绕过这一限制 可以让静态注册接收到隐式广播的,但没发现特别好的,若非必要 也不需要这样做。自定义的广播一般知道目标接收器的组件等信息的,而且动态注册(后面讲的)不受这一限制。
官网上说明:
Android 8.0
Beginning with Android 8.0 (API level 26), the system imposes additional restrictions on manifest-declared receivers. If your app targets Android 8.0 or higher, you cannot use the manifest to declare a receiver for most implicit broadcasts
(broadcasts that don't target your app specifically). You can still use a context-registered receiver when the user is actively using your app.
这里就不发送隐式广播就可以接收了。
Button sendBroadcastBtn = findViewById(R.id.send_broadcast_btn);
sendBroadcastBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d("StaticBroadcastReceiver", "click");
Intent broadcastIntent = new Intent();
broadcastIntent.setAction("com.flx.testBroadcastReceiver.TEST_BROADCAST_RECEIVER");
broadcastIntent.putExtra("testkey", "testval");
broadcastIntent.setPackage("com.flx.testBroadcastReceiver");
sendBroadcast(broadcastIntent);
}
});
2019-07-31 03:46:24.810 21336-21336/com.flx.testBroadcastReceiver D/StaticBroadcastReceiver: click
2019-07-31 03:46:24.857 21336-21336/com.flx.testBroadcastReceiver D/StaticBroadcastReceiver: onReceive: testval
(2)动态注册
动态注册,需要在代码中通过registerReceiver(BroadcastReceiver receiver, IntentFilter filter)进行注册 的。只有当广播接收者通过registerReceiver()注册后,才能接收广播进行处理。
动态注册不受隐式广播的限制。
动态注册的广播通过unregisterReceiver(BroadcastReceiver receiver)去销毁,否则会报错。
动态注册非常驻系统,受组件生命周期影响,适用于在特定时刻监听广播的场景。
动态广播接收器
public class DanymicBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Log.d("flx_broadcast", "DanymicBroadcastReceiver onReceive: " + intent.getStringExtra("testkey"));
}
}
动态注册和销毁
import android.app.Activity;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button; public class MainActivity extends Activity {
final private String TEST_ACTION = "com.flx.testBroadcastReceiver.TEST_BROADCAST_RECEIVER";
private DanymicBroadcastReceiver mDanymicBroadcastReceiver = new DanymicBroadcastReceiver(); @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); Button sendBroadcastBtn = findViewById(R.id.send_broadcast_btn);
sendBroadcastBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d("flx_broadcast", "click");
Intent broadcastIntent = new Intent();
broadcastIntent.setAction(TEST_ACTION);
broadcastIntent.putExtra("testkey", "testval");
// broadcastIntent.setPackage("com.flx.testBroadcastReceiver");
sendBroadcast(broadcastIntent);
}
}); IntentFilter intentFilter = new IntentFilter(TEST_ACTION);
registerReceiver(mDanymicBroadcastReceiver, intentFilter);
} @Override
protected void onDestroy() {
unregisterReceiver(mDanymicBroadcastReceiver);
super.onDestroy();
}
}
2.其他注意点
广播也有ANR的限定时间,10s。10s内onReceive()如果仍没处理完,就会报ANR。所以对于耗时的操作,可以通过intent,启动其他组件或服务进行处理。
三、有序广播
上面基本用法里讲到的是普通广播。某些特定场景,需要用到有序广播,有序广播 可以根据设定好的优先级,依次处理。可以传参数,可以中断后续广播接收器的处理等操作。
注意点:
1.优先级的设置:静态注册的通过<intent-filter android:priority="">设置,动态注册通过intentFilter1.setPriority(100)。 优先级的值范围是-1000~1000。
setPriority
Added in API level 1
fun setPriority(priority: Int): Unit
Modify priority of this filter. This only affects receiver filters. The priority of activity filters are set in XML and cannot be changed programmatically.
The default priority is 0. Positive values will be before the default, lower values will be after it. Applications should use a value that
is larger than SYSTEM_LOW_PRIORITY and smaller than SYSTEM_HIGH_PRIORITY .
SYSTEM_LOW_PRIORITY Value: -1000
SYSTEM_HIGH_PRIORITY Value: 1000
2.有序广播 可以向低优先级的广播接收器传递数据,也可以终止传播。下面的例子有相关操作。
主要代码如下:
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button; public class MainActivity extends Activity {
final private String TEST_ACTION = "com.flx.testBroadcastReceiver.TEST_BROADCAST_RECEIVER";
private MyBroadcast1 mMyBroadcast1 = new MyBroadcast1();
private MyBroadcast2 mMyBroadcast2 = new MyBroadcast2();
private MyBroadcast3 mMyBroadcast3 = new MyBroadcast3(); @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); Button sendBroadcastBtn = findViewById(R.id.send_broadcast_btn);
sendBroadcastBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d("flx_broadcast", "click");
Intent broadcastIntent = new Intent();
broadcastIntent.setAction(TEST_ACTION);
broadcastIntent.putExtra("testkey", "testval");
// broadcastIntent.setPackage("com.flx.testBroadcastReceiver");
// sendBroadcast(broadcastIntent);
sendOrderedBroadcast(broadcastIntent, null);
}
}); IntentFilter intentFilter1 = new IntentFilter(TEST_ACTION);
intentFilter1.setPriority();
registerReceiver(mMyBroadcast1, intentFilter1); IntentFilter intentFilter2 = new IntentFilter(TEST_ACTION);
intentFilter2.setPriority();
registerReceiver(mMyBroadcast2, intentFilter2); IntentFilter intentFilter3 = new IntentFilter(TEST_ACTION);
intentFilter3.setPriority();
registerReceiver(mMyBroadcast3, intentFilter3);
} @Override
protected void onDestroy() {
unregisterReceiver(mMyBroadcast1);
unregisterReceiver(mMyBroadcast2);
unregisterReceiver(mMyBroadcast3);
super.onDestroy();
} public class MyBroadcast1 extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
Log.d("flx_broadcast", "MyBroadcast1 onReceive:" );
}
} public class MyBroadcast2 extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
Log.d("flx_broadcast", "MyBroadcast2 onReceive:"+getResultData());
abortBroadcast();
}
} public class MyBroadcast3 extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
setResultData("MyBroadcast3 set string is aaaa");
Log.d("flx_broadcast", "MyBroadcast3 onReceive:" );
}
}
}
这里点击后打印出的log如下:
2019-07-31 05:17:27.459 26243-26243/com.flx.testBroadcastReceiver D/flx_broadcast: click
2019-07-31 05:17:27.486 26243-26243/com.flx.testBroadcastReceiver D/flx_broadcast: MyBroadcast3 onReceive:
2019-07-31 05:17:27.495 26243-26243/com.flx.testBroadcastReceiver D/flx_broadcast: MyBroadcast2 onReceive:MyBroadcast3 set string is aaaa
MyBroadcast3设置的优先级最高300,其次是MyBroadcast2 200,MyBroadcast1 100。由于MyBroadcast3中通过setResultData()设置了数据传到了MyBroadcast2,MyBroadcast2中abortBroadcast()停止了传播。所以log如上。
把setResultData()和abortBroadcast()注释掉后,就完全按照优先级先后执行了。log如下。
2019-07-31 05:23:15.840 26634-26634/com.flx.testBroadcastReceiver D/flx_broadcast: click
2019-07-31 05:23:15.872 26634-26634/com.flx.testBroadcastReceiver D/flx_broadcast: MyBroadcast3 onReceive:
2019-07-31 05:23:15.889 26634-26634/com.flx.testBroadcastReceiver D/flx_broadcast: MyBroadcast2 onReceive:null
2019-07-31 05:23:15.897 26634-26634/com.flx.testBroadcastReceiver D/flx_broadcast: MyBroadcast1 onReceive:
Android_四大组件之BroadcastReceiver的更多相关文章
- [置顶] Android四大组件之BroadcastReceiver
Android四大组件之BroadcastReceiver Broadcast Receiver 广播接收器,是一种负责接收广播消息并对消息做出响应的组件,和Service一样并不提供与用户交互的UI ...
- Android实训案例(六)——四大组件之一BroadcastReceiver的基本使用,拨号,短信,SD卡,开机,应用安装卸载监听
Android实训案例(六)--四大组件之一BroadcastReceiver的基本使用,拨号,短信,SD卡,开机,应用安装卸载监听 Android中四大组件的使用时重中之重,我这个阶段也不奢望能把他 ...
- Android 四大组件之“ BroadcastReceiver ”
前言 Android四大组件重要性已经不言而喻了,今天谈谈的是Android中的广播机制.在我们上学的时候,每个班级的教室里都会装有一个喇叭,这些喇叭都是接入到学校的广播室的,一旦有什么重要的通知,就 ...
- Android四大组件:BroadcastReceiver 介绍
介绍 BroadcastReceiver 即广播组件,是 Android 的四大组件之一.用于监听和接收广播消息,并做出响应.有以下一些应用: 不同组件之间的通信(应用内或不同应用之间). 多线程之间 ...
- Android_四大组件之Service
一.概述 Service是四大组件之一.它主要用于在后台执行耗时的逻辑,即使用户切换到其他应用甚至退出应用,它也能继续在后台运行. 下面主要介绍了service的两种形式启动和绑定 ,并通过简单例子说 ...
- 四大组件之BroadcastReceiver
BroadcastReceiver,顾名思义就是“广播接收者”的意思,它是Android四大基本组件之一,这种组件本质上是一种全局的监听器,用于监听系统全局的广播消息.它可以接收来自系统和应用的的广播 ...
- Android四大组件之BroadcastReceiver
什么是BroadcastReceiver? BroadcastReceiver也就是“广播接收者”的意思,顾名思义,它就是用来接收来自系统和应用中的广播. 在Android系统中,广播体现在方方面面, ...
- 四大组件之BroadcastReceiver基础
1. 系统广播 1.1 动态注册 (1)创建自定义接收器类继承自BroadcaseReceiver,实现onReceive()方法,对接收到的广播的逻辑处理就是写在这个函数中的. (2)实例化 ...
- Android四大组件之—— BroadcastReceiver的使用
BroadcastReceiver又名广播接收者.既然它用于接收广播,那一定就有人负责发送. Android系统中的广播: 在现实生活中,我们都知道广播是什么,用来做什么.例如公园里的广播,主要通知游 ...
随机推荐
- [NOI 2020 Online] 入门组T1 文具采购(洛谷 P6188)题解
原题传送门 题目部分:(来自于考试题面,经整理) [题目描述] 小明的班上共有 n 元班费,同学们准备使用班费集体购买 3 种物品: 1.圆规,每个 7 元. 2.笔,每支 4 元. 3.笔记本,每本 ...
- shell之路 shell核心语法【第三篇】运算
Bash 支持很多运算符,包括算数运算符.关系运算符.布尔运算符.字符串运算符和文件测试运算符. 原生bash不支持简单的数学运算,默认都是字符串操作,但是可以通过其他命令来实现 算数运算 expr. ...
- 关于【MySQL 子查询——查询最大值】的补充说明
昨天在使用子查询查找最高分和最低分时遇上了一点问题,情况是这样的:如果找到的最高分或最低分是唯一值则不会有什么问题,但如果有其它班级学生的成绩恰好与查询的最高分或最低分相同时就会把那个学生的信息也显示 ...
- html之表单元素form
表单元素form \(都是嵌套input标签来实现,其中type属性选择不同则不同\) \(text:文本内容(输入内容可见)\) \(password:密码(输入内容不可见)\) \(submit: ...
- 设计模式(Java语言)- 建造者模式
前言 在日常的生活中,我们可以经常看到建造者模式的影子.比如,建造房子,那么房子就是一个产品,房子由门,窗,墙,地板等部门组成.然后包工头在建造房子的时候就根据设计好的图纸来建造,但是包工头并不是亲自 ...
- Java 四种权限修饰符
Java 四种权限修饰符访问权限 public protected (default) private 同一个类(我自己) yes yes yes yes 同一包(我邻居) yes yes yes n ...
- 【BIM】BIMFACE中实现电梯实时动效
背景 在运维场景中,电梯作为运维环节重要的一部分是不可获缺的,如果能够在三维场景中,将逼真的电梯效果,包括外观.运行状态等表现出来,无疑是产品的一大亮点.本文将从无到有介绍如何在bimface中实现逼 ...
- 手把手教你撸一套Redux(Redux源码解读)
Redux 版本:3.7.2 Redux 是 JavaScript 状态容器,提供可预测化的状态管理. 说白了Redux就是一个数据存储工具,所以数据基础模型有get方法,set方法以及数据改变后通知 ...
- 数学建模(二)优劣解距离法Topsis模型部分
步骤: (一)统一指标类型:指标正向化(转化为极大型)(论文) 越大越好极大型指标,效益型指标 越小越好极小型指标,成本型指标 max-x,max=max{xi} 落在某个区间[a,b]是最好的,区间 ...
- js判断数组(数组对象)中是否存在指定的值,如果存在就删除
数组中是否存在指定值,存在就删除 var str = ["a", "b", "c"]; var index = str.indexOf(&q ...