一、概述

BroadcastReceiver是广播接收器,接收来自 系统或应用发出的广播信息 并进行相应的逻辑处理。

自定义BroadcastReceiver只需继承android.content.BroadcastReceiver,并重写onReceive()方法就可以了。

public class StaticBroadcastReceiver extends BroadcastReceiver {@Overridepublic 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";@Overridepublic 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() {@Overridepublic 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 {@Overridepublic 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();@Overrideprotected 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() {@Overridepublic 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(100);registerReceiver(mMyBroadcast1, intentFilter1);IntentFilter intentFilter2 = new IntentFilter(TEST_ACTION);intentFilter2.setPriority(200);registerReceiver(mMyBroadcast2, intentFilter2);IntentFilter intentFilter3 = new IntentFilter(TEST_ACTION);intentFilter3.setPriority(300);registerReceiver(mMyBroadcast3, intentFilter3);}@Overrideprotected void onDestroy() {unregisterReceiver(mMyBroadcast1);unregisterReceiver(mMyBroadcast2);unregisterReceiver(mMyBroadcast3);super.onDestroy();}public class MyBroadcast1 extends BroadcastReceiver{@Overridepublic void onReceive(Context context, Intent intent) {Log.d("flx_broadcast", "MyBroadcast1 onReceive:" );}}public class MyBroadcast2 extends BroadcastReceiver{@Overridepublic void onReceive(Context context, Intent intent) {Log.d("flx_broadcast", "MyBroadcast2 onReceive:"+getResultData());
            abortBroadcast();
        }}public class MyBroadcast3 extends BroadcastReceiver{@Overridepublic 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:

转载于:https://www.cnblogs.com/fanglongxiang/p/11281466.html

Android_组件_BroadcastReceiver基础相关推荐

  1. [Vue 牛刀小试]:第八章 - 组件的基础知识

    一.前言 在之前的学习中,我们对于 Vue 的一些基础语法进行了简单的了解,通过之前的代码可以清晰的看出,我们在使用 Vue 的整个过程,最终都是在对 Vue 实例进行的一系列操作. 这里就会引出一个 ...

  2. 学习VUE第七天课程(VUE之组件(基础、分类、命名))

    VUE之组件(基础.分类.命名) 组件( Component )是 Vue.js 最核心的功能,也是整个框架设计最精彩的地方,当然也是最难掌握的. 接下来会由浅入深地学习组件的全部内容,并通过几个案例 ...

  3. 【精讲】vue组件开发基础、多层嵌套(内含详细注释)、vuecomponent构造函数

    目录 vue组件开发基础 多层嵌套(内含详细注释) vuecomponent构造函数 第一部分:vue组件开发基础 <!--         vue中使用组件的三大步骤:         一 , ...

  4. c# 无法加载oraops.dll_Robotstudio软件二次开发:基于C#语言的Smart组件开发基础

    Robotstudio软件除了支持Add-Ins插件的二次开发以外,还支持Smart组件的二次开发.开发语言同样是基于.NET框架的C#语言或VB语言.Smart组件是Robotstudio软件中实现 ...

  5. 接触VC之四:COM组件模型基础

    From: http://daimajishu.iteye.com/blog/1081292 一年又一年,已经又过了一年了.我VC的生涯已经两岁了.可以相当地庆贺一下哟.回顾这一年的学习(唉,还没有工 ...

  6. Android Navigation 组件(基础篇)

    一.前言 在日常开发中,越来越多的会使用到一个activity嵌套多个fragment的场景,典型的例子就是app的首页,一般都会由一个activity+多个Fragment组成的底部导航界面,那对于 ...

  7. 前端学习-Antd 组件库基础

    一.概述 Antd 组件较多,这里介绍一些常用的组件,更详细的说明可以参考官方文档:组件总览 - Ant Design,本文章为此基础上进行整理. 1.安装 yarn add antd 或者 npm ...

  8. c#获取autocad安装位置_Robotstudio软件二次开发:基于C#语言的Smart组件开发基础

    Robotstudio软件除了支持Add-Ins插件的二次开发以外,还支持Smart组件的二次开发. 开发语言同样是基于 .NET框架的C#语言或VB语言. Smart组件是Robotstudio软件 ...

  9. Material Design风格神框架vuetify 学习笔记(十二) 组件的基础

    一. 窗口 v-window v-window 被设计成可以轻松地循环浏览内容,它提供了一个简单的接口来创建真正的自定义实现. v-window组件提供了将内容从一个窗格过渡到另一个窗格的基础功能. ...

最新文章

  1. rest服务器性能,基于真实应用环境下的 WEB REST API 性能测试
  2. 前端开发大众手册(转)
  3. 电子老鼠闯迷宫pascal解题程序
  4. boost::mp11::mp_insert_c相关用法的测试程序
  5. 云+X案例展 | 电商零售类:WakeData助力叁拾加数字化变革
  6. [Java] 蓝桥杯ADV-155 算法提高 上帝造题五分钟
  7. 信息发布系统 Jquery+MVC架构开发(6)BLL层提供WCF 服务 .
  8. 明天省赛,我都还不太熟悉Dev - C++,怎么切换成C++11了?它的报错看不懂呀,那花八分钟看看这篇文章吧~解决你的困惑。
  9. 无线广播风暴问题定位分析(omnipeek工具)
  10. 工程施工阶段成本变化
  11. OpenCV—python 图像矫正(基于傅里叶变换—基于透视变换)
  12. 透明这种颜色的html,透明颜色HTML5帆布
  13. 每月一书(202102):《人类简史》
  14. 数据结构实验报告,二叉树的基本操作(C语言)
  15. Swift如何判断字符串的语言
  16. 中国最大–深圳企业列表
  17. Spring Webflux 响应式编程 (二) - WebFlux编程实战
  18. 用于计算圆柱体体积和面积的Python程序
  19. 【阅读论文】博-自动化眼底图像分析技术可筛查糖尿病患者的视网膜疾病--第三章--QA
  20. 安卓虚拟键盘_安卓手机也能装Windows,你还不知道吗?

热门文章

  1. SpringSecurity系列(三) Spring Security 表单登录
  2. 【链表】剑指offer:反转链表
  3. LeetCode 300最长递增子序列
  4. 开源数字媒体资产管理系统:Razuna安装方法
  5. C++从文件中查找特定的字符串,并提取该字符串
  6. controller层要写什么_别再写满屏的try-catch了,真丑,全局异常处理不会吗?
  7. linux apache 2.2下载,Apache HTTP Server 2.2.26 发布下载
  8. linux 生成2g文件吗,linux 32位系统 c++写大于2G文件
  9. 【SCOI2005】【BZOJ1083】繁忙的都市(MST模板)
  10. 【编辑器】Notepad++相关