当前位置:首页 » 安卓系统 » android广播用法

android广播用法

发布时间: 2023-03-02 07:07:38

❶ android中的广播怎么使用

广播操作有两种
1、发送广播,就是你自己发送出去一个广播,让别人接收
2、接收广播,这个是自己实现一个广播接收器,接收那些你自己过滤的广播,然后处理
具体的代码实现,可以在网上找找

❷ 说说Android的广播(1)

对于Activity的启动流程,我们已经有了几个版本的分析了。这里我们分析一个更容易一些的,四大组件中最简单的Broadcast Receiver。

关于Broadcast,有几点需要了解。首先是广播的类型,然后是广播的发送方法,最后是广播是如何被接收的。这三者相辅相承的,比如普通广播和有序广播只有在详细了解了广播的接收过程了之后,才能真正明白它的含义。

普通的广播是不在意顺序的,最简单的理解是同时可以收到这个广播。如果应用是动态注册这个广播的,且广播发送时这个进程还活着,那么当然可以并发的把广播尽快地传送出去是最好的。
但是,如果是通过AndroidManifest.xml静态注册的情况,也就是说这个广播首先要把一个进程启动起来,这时并发启动很多进程就是个问题了。Android目前的做法是,对这种静态的广播接收者,自动按有序广播的方式来串行处理。但是这对应用是透明的,应用不能假设系统已经把静态的无序广播当成有序广播来处理。

这个时候讲粘性广播有福了,因为从Android 5.0(API 21)开始,因为安全性的问题,官方已经正式废弃了粘性广播。

Context类提供两个方法可以用于发送普通广播:

差别是第二个设置权限。

发给特定的用户:

有序广播因为要处理消息的处理结果,所以要复杂一些。

如果只是想让广播可以按优先级来收取,并不在意处理的结果,可以用下面的版本:

同样,在多用户环境下,也可以选择给哪个用户发广播:

不管是普通的还是有序的广播都对应有粘性的版本:

以上的API都是定义于Context类中: https://developer.android.com/reference/android/content/Context.html

首先我们先看看发送端是如何发送的。
我们首先先放一个大图,让大家先有一个直观的印象,不管普通广播、有序广播、粘性广播如何组合,最终都汇集到一个大方法中。

我们先看应用发送普通广播的一个简单的例子:

非常简单,调用ContentWrapper的sendBroadcast方法就可以了。
然后我们顺藤摸瓜就好了。
Activity中的sendBroadcast,实际上调用的是:

我们来看frameworks/base/core/java/android/content/ContextWrapper.java中对sendBroadcast的定义:

ContextWrapper只是一个包装,真正的实现在ContextImpl中

我们来看/frameworks/base/core/java/android/app/ContextImpl.java中真正实现sendBroadcast的功能:

它会通过IPC去调用AMS的broadcastIntent。由于我们这个普通的广播的方法参数最少,所以好多都是传null。

加锁,定参数,然后调用真正的逻辑的实现。

我们先把broadcastIntentLocked的真正逻辑放一下,先看看有序广播是如何发送的。

ContextWrapper.sendOrderedBroadcast

Context是abstract方法,调用的是ContextWrapper的实现:

跟普通广播一样,还是会调用到ContextImpl.sendOrderedBroadcast

有序广播调用broadcastIntent的区别在于serialized参数,普通广播为false,有序广播为true.

原型为:

前面讲过带有回调的版本,我们看看它是如何实现的:

当然还是调用ContextImpl.sendOrderedBroadcast

这次变成只是一个封装了,它会调用一个更多参数的版本:

这次是一个全参数调用broadcastIntent的版本了,除了sticky就齐了

我们也不绕圈子了,直接看ContextImpl.sendStickyBroadcast.

❸ Android启动广播时怎样往广播中传递参数

在android中使用广播来让其他监听广播的地方能够对相应的事情做处理,但有的时候需要传递一些其他的附带值,而这个时候是可以直接用播放广播的intent来传递的。x0dx0a例:x0dx0aIntent intent = new Intent();x0dx0aintent.putExtra("msgPersons", msgPersons);x0dx0aintent.setAction(Constant.hasMsgUpdatedAction);x0dx0aintent.putExtra("userId", userId);x0dx0aintent.putExtra("msgCount", messages.size());x0dx0asendBroadcast(intent);

❹ Android系统广播(Broadcast)注册,发送,接收流程解析

以下广播简称Broadcast

   是Android四大组件之一,在四大组件的另外两个组件 和 拥有发送和接收广播的能力。Android 是在 进程间通信机制的基础上实现的,内部基于消息发布和订阅的事件驱动模型,广播发送者负责发送消息,广播接收者需要先订阅消息,然后才能收到消息。 进程间通信与 的区别在于:

   有三种类型

   存在一个注册中心,也可以说是一个调度中心,即 。广播接收者将自己注册到 中,并指定要接收的广播类型;广播发送者发送广播时,发送的广播首先会发送到 , 根据广播的类型找到对应的 ,找到后边将广播发送给其处理。

   这里以普通广播为例子, 接收者有两种注册方式,一种是 ,一种是 :

(广播的发送分为 两种,这里针对有序的广播) 中的android:priority=""和 中的IntentFilter.setPriority(int)可以用来设置广播接收者的优先级,默认都是0 , 范围是[-1000, 1000],值越大优先级越高,优先级越高越早收到。

   在相同优先级接收同个类型广播时, 的广播接收器比 的广播接收者更快的接收到对应的广播,这个之后会进行分析。

   注:以下源码基于rk3399_instry Android7.1.2

   的流程可分为 , 和 三个部分,这里依次分析下

   在Android系统的 机制中,前面提到, 作为一个注册和调度中心负责注册和转发 。所以 的注册过程就是把它注册到 的过程。

   这里我们分析 广播的过程, 和 有一个共同的父类 ,所以它们对应的注册过程其实是调用 ,接下来我们按照流程逐步分析调用流程的源码。

frameworks/base/core/java/android/content/ContextWrapper.java

   在之前的 Android应用程序启动入口ActivityThread.main流程分析 分析过,在我们启动 Activity 时会创建一个 对象,然后通过 传给我们启动的 ,其内部就会将该对象赋值给 ; 的 方法也是类似的赋值流程,这里放个简易的源码应该更好理解

   可以看到最后都会将生成的 对象赋值给对应的
对象。接下来继续分析 , 即 函数。

/frameworks/base/core/java/android/app/ContextImpl.java

   这里我们首先看下如何将广播接收者 封装成一个 接口的 本地对象
/frameworks/base/core/java/android/app/LoadedApk.java

   每一个注册过广播接收者的 或 组件在<font color='Crimson'> LoadedApk </font>类中都有个对应的 对象,该对象负责将 与 组件关联起来。这些对象,以关联的 作为关键字保存在一个 中。之后对应的 又以 的 作为关键字保存在 的成员变量 对象中。最后通过 对应的 方法获得其 接口的 本地对象。之后再回到 注册方法内,将 对象发给 进行注册。

/frameworks/base/core/java/android/app/ActivityManagerNative.java

/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

   在的 或 注册一个 时,并不是将其注册到<font color='OrangeRed'>AMS</font>中,而是将与它关联的<font color='OrangeRed'>InnerReceiver</font>对象注册到<font color='OrangeRed'>AMS</font>中,当<font color='OrangeRed'>AMS</font>接收到广播时,会根据 在内部找到对应的<font color='OrangeRed'>InnerReceiver</font>对象,然后在通过这个对象将这个广播发送给对应的 处理。

   注册过程这边画了一个简单的流程图:

   <font color='OrangeRed'>Broadcast</font>的发送过程可简单描述为以下几个过程:

frameworks/base/core/java/android/content/ContextWrapper.java

/frameworks/base/core/java/android/app/ContextImpl.java

/frameworks/base/core/java/android/app/ActivityManagerNative.java

/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

❺ Android 使用广播系统解决app开机自启动问题

关注 【网罗开发】微信公众号,回复【160】便可领取。
网罗天下方法,方便你我开发 ,更多Android技术干货等待领取,所有文档会持续更新,欢迎关注一起成长!

总结一下使用ACTION_BOOT_COMPLETED的广播,解决app开机自启动的问题
1.首先在你的工程上建一个广播接受的类,继承BroadcastReceiver:

2.然后要在AndroidManifest.xml中加入权限和配置相关信息:

3.在application标签中,配置以下相关信息:

补充说明:
1.查看系统中是否安装了类似360管家的软件,为了加快开机速度,默认是关闭掉开机广播的,只需要在设置中打开即可。
2.如果监听不到广播,可以尝试同时监听广播和sd卡。
3.同时监听广播和sd卡,在application标签中,配置以下相关信息:

❻ 22 AndroidBroadcast广播机制

广播(Broadcast)机制用于进程/线程间通信,广播分为广播发送和广播接收两个过程,其中广播接收者BroadcastReceiver便是Android四大组件之一。

BroadcastReceiver分为两类:

从广播发送方式可分为三类:

广播在系统中以BroadcastRecord对象来记录, 该对象有几个时间相关的成员变量.

广播注册,对于应用开发来说,往往是在Activity/Service中调用 registerReceiver() 方法,而Activity或Service都间接继承于Context抽象类,真正干活是交给ContextImpl类。另外调用getOuterContext()可获取最外层的调用者Activity或Service。

[ContextImpl.java]

其中broadcastPermission拥有广播的权限控制,scheler用于指定接收到广播时onRecive执行线程,当scheler=null则默认代表在主线程中执行,这也是最常见的用法

[ContextImpl.java]

ActivityManagerNative.getDefault()返回的是ActivityManagerProxy对象,简称AMP.
该方法中参数有mMainThread.getApplicationThread()返回的是ApplicationThread,这是Binder的Bn端,用于system_server进程与该进程的通信。

[-> LoadedApk.java]

不妨令 以BroadcastReceiver(广播接收者)为key,LoadedApk.ReceiverDispatcher(分发者)为value的ArrayMap 记为 A 。此处 mReceivers 是一个以 Context 为key,以 A 为value的ArrayMap。对于ReceiverDispatcher(广播分发者),当不存在时则创建一个。

此处mActivityThread便是前面传递过来的当前主线程的Handler.

ReceiverDispatcher(广播分发者)有一个内部类 InnerReceiver ,该类继承于 IIntentReceiver.Stub 。显然,这是一个Binder服务端,广播分发者通过rd.getIIntentReceiver()可获取该Binder服务端对象 InnerReceiver ,用于Binder IPC通信。

[-> ActivityManagerNative.java]

这里有两个Binder服务端对象 caller 和 receiver ,都代表执行注册广播动作所在的进程. AMP通过Binder驱动将这些信息发送给system_server进程中的AMS对象,接下来进入AMS.registerReceiver。

[-> ActivityManagerService.java]

其中 mRegisteredReceivers 记录着所有已注册的广播,以receiver IBinder为key, ReceiverList为value为HashMap。

在BroadcastQueue中有两个广播队列mParallelBroadcasts,mOrderedBroadcasts,数据类型都为ArrayList<broadcastrecord style="box-sizing: border-box;">:</broadcastrecord>

mLruProcesses数据类型为 ArrayList<ProcessRecord> ,而ProcessRecord对象有一个IApplicationThread字段,根据该字段查找出满足条件的ProcessRecord对象。

该方法用于匹配发起的Intent数据是否匹配成功,匹配项共有4项action, type, data, category,任何一项匹配不成功都会失败。

broadcastQueueForIntent(Intent intent)通过判断intent.getFlags()是否包含FLAG_RECEIVER_FOREGROUND 来决定是前台或后台广播,进而返回相应的广播队列mFgBroadcastQueue或者mBgBroadcastQueue。

注册广播:

另外,当注册的是Sticky广播:

广播注册完, 另一个操作便是在广播发送过程.

发送广播是在Activity或Service中调用 sendBroadcast() 方法,而Activity或Service都间接继承于Context抽象类,真正干活是交给ContextImpl类。

[ContextImpl.java]

[-> ActivityManagerNative.java]

[-> ActivityManagerService.java]

broadcastIntent()方法有两个布尔参数serialized和sticky来共同决定是普通广播,有序广播,还是Sticky广播,参数如下:

broadcastIntentLocked方法比较长,这里划分为8个部分来分别说明。

这个过程最重要的工作是:

BroadcastReceiver还有其他flag,位于Intent.java常量:

主要功能:

这个过主要处于系统相关的10类广播,这里不就展开讲解了.

这个过程主要是将sticky广播增加到list,并放入mStickyBroadcasts里面。

其他说明:

AMS.collectReceiverComponents

广播队列中有一个成员变量 mParallelBroadcasts ,类型为ArrayList<broadcastrecord style="box-sizing: border-box;">,记录着所有的并行广播。</broadcastrecord>

动态注册的registeredReceivers,全部合并都receivers,再统一按串行方式处理。

广播队列中有一个成员变量 mOrderedBroadcasts ,类型为ArrayList<broadcastrecord style="box-sizing: border-box;">,记录着所有的有序广播。</broadcastrecord>

发送广播过程:

处理方式:

可见不管哪种广播方式,都是通过broadcastQueueForIntent()来根据intent的flag来判断前台队列或者后台队列,然后再调用对应广播队列的scheleBroadcastsLocked方法来处理广播;

在发送广播过程中会执行 scheleBroadcastsLocked 方法来处理相关的广播

[-> BroadcastQueue.java]

在BroadcastQueue对象创建时,mHandler=new BroadcastHandler(handler.getLooper());那么此处交由mHandler的handleMessage来处理:

由此可见BroadcastHandler采用的是”ActivityManager”线程的Looper

[-> BroadcastQueue.java]

此处mService为AMS,整个流程还是比较长的,全程持有AMS锁,所以广播效率低的情况下,直接会严重影响这个手机的性能与流畅度,这里应该考虑细化同步锁的粒度。

❼ android 之广播机制

Android 中的广播主要可以分为两种类型:标准广播和有序广播

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

标准广播工作示意图:

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

有序广播工作示意图:

可以让程序在未启动的情况下接收广播

在Android 8.0系统之后,所有隐式广播都不允许使用静态注册的方式来接收了。隐式广播指的是那些没有具体指定发送给哪个应用程序的广播,大多数系统广播属于隐式广播,但是少数特殊的系统广播目前仍然允许使用静态注册的方式来接收,详见网址: https://developer.android.google.cn/guide/components/broadcast-exceptions.html

在 AndroidManifest.xml 文件中注册

在 AndroidManifest.xml 文件中进行权限声明

不要在 onReceive() 方法中添加过多的逻辑或者进行任何的耗时操作,因为BroadcastReceiver中是不允许开启线程的,当 onReceive() 方法运行了较长时间而没有结束时,程序就会出现错误

先定义一个BroadcastReceiver来准备接收此广播

在 AndroidManifest.xml 文件中注册

有序广播是一种同步执行的广播,并且是可以被截断的。为了验证这一点,我们需要再创建一个新的BroadcastReceiver。新建AnotherBroadcastReceiver

同样,在 AndroidManifest.xml 文件中注册,同时,使用 intent-filter 标签的 android:priority 属性设置优先级

前面的 AnotherBroadcastReceiver 的优先级比较高,因此 AnotherBroadcastReceiver 一定比 MyBroadcastReceiver 先收到广播,因此,可以在 AnotherBroadcastReceiver 的 onReceive 方法中使用 abortBroadcast() 方法截断广播,这样 MyBroadcastReceiver 就收不到该广播了

在界面上弹出一个对话框,让用户无法进行任何其他操作,必须点击对话框中的“确定”按钮,关闭所有的Activity,然后回到登录界面即可

ActivityCollector 类用于管理所有的Activity,具有关闭所有Activity的功能

创建 BaseActivity 类作为所有 Activity 的父类,并在里面实现强制下线功能,在这里实现此功能,有以下几点原因

创建一个LoginActivity来作为登录界面

activity_login.xml

LoginActivity 如果输入 123 就到 MainActivity界面

MainActivity 中点击强制下线按钮,就发送强制下线的广播

MainActivity 布局

❽ Android BroadcastReceiver详解

BroadcastReceiver(广播接收器)是Android四大组件之一,顾名思义,通过广播的方式进行消息传递,其本质是一个全局的监听器,可以监听到各种广播,可以用来实现不同组件之间的通信。广播最大的特点就是发送方并不关心接收方是否接到数据,也不关心接收方是如何处理数据的,通过这样的形式来达到接、收双方的完全解耦合。

又称无序广播,这种广播完全是异步的,所有与广播Intent匹配的BroadcastReceiver,都可以收到这条广播,并且不分先后顺序,视为同时收到,通过Context.sendBroadcast()方法发送。这种广播的效率比较高,但缺点是接收器不能将处理结果传递给下一个接收器,并且无法在中途终止广播。

这是一种同步执行的广播,通过Context.sendOrderedBroadcast()方法发送,这种广播发出后,通过receiver的intent-filter中的android:priority属性来设置优先级,优先级从-1000~1000,数越大,优先级越高,使用setResult()方法把结果传递给下一个接收者,通过getResult()方法获取上一个接收者传递过来的结果,并可以通过abortBroadcast()方法丢弃该广播,使该广播不再传递给下一个接收者。

粘性广播通过Context.sendStickBroadcast()方法来发送,用此方法发送的广播会一直滞留,当有匹配此广播的接收器被注册后,该广播接收器就会收到此广播。使用此广播时,需要获得BROADCAST_STICKY权限。(在 android 5.0/api 21后不再推荐使用)

Android系统中内置了多个系统广播,只要涉及到手机的基本操作,基本上都会发出相应的系统广播。如:开启启动,网络状态改变,拍照,屏幕关闭与开启,点亮不足等等。每个系统广播都具有特定的intent-filter,其中主要包括具体的action,系统广播发出后,将被相应的BroadcastReceiver接收。系统广播在系统内部当特定事件发生时,有系统自动发出。

以上广播都属于全局广播,发出去的广播,只要有匹配的接收者,就可以收到广播。这样一来会造成一些问题,一是消耗性能,二是容易引起安全性的问题,为了能够简单的解决这方面的问题,Android引入了一套广播本地广播机制,使用该机制发出的广播只能够在本应用内部进行传递,并且广播接收器也只能接收来自本应用发出的广播。

使用方法
1.注册本地广播接收器

2.发送本地广播

3.注销本地广播接收器

本文用到的BroadcastReceiver

Android 8.0(API级别26)取消大部分静态注册广播,建议使用动态广播
https://developer.android.google.cn/about/versions/oreo/android-8.0

❾ android 广播机制(2) 粘性广播

android的粘性广播,是指广播接收器一注册马上就能接收到广播的一种机制,当然首先系统要存在广播。而普通广播就是要先注册广播接收器,然后广播被发送到系统,广播接收器才能接收到广播。
所以他们的区别是:
粘性广播调用registerReceiver能马上接受广播,而普通广播不行。

对于粘性广播:
1.系统首先存在粘性广播

2.注册广播接收器

3.处理广播

下面用一个例子展示下他们的区别
主Acitivity

布局

布局有两个按钮,一个是注册粘性广播,一个是注册普通广播。点击注册粘性广播按钮会马上返回结果。而点击注册普通广播按钮则没有反应

热点内容
数据结构与算法笔试题 发布:2025-05-15 01:04:20 浏览:416
搜狗输入法如何直接编辑配置文件 发布:2025-05-15 00:51:47 浏览:668
电箱都有哪些配置 发布:2025-05-15 00:30:21 浏览:74
安卓qq邀请码在哪里寻找 发布:2025-05-15 00:02:04 浏览:34
三菱fx编程口 发布:2025-05-15 00:01:23 浏览:810
医院招商引资宣传片脚本 发布:2025-05-15 00:01:21 浏览:368
linuxcftp服务器 发布:2025-05-14 23:58:18 浏览:718
探岳什么配置才有驾驶模式选择 发布:2025-05-14 23:53:17 浏览:146
如何在手机上看无限流量密码 发布:2025-05-14 23:43:31 浏览:114
19投篮脚本 发布:2025-05-14 23:36:57 浏览:513