当前位置:首页 » 安卓系统 » 安卓广播在哪个线程

安卓广播在哪个线程

发布时间: 2023-03-29 09:18:14

⑴ android系统睡眠状态如何唤醒线程和广播

不能!
(不能手动唤醒,因为肯定需要点亮屏幕(手动点亮屏幕),所以并不是真睡眠状态)。
只能提前设置,比如闹钟,具体到“广播”即收音机,那么只建议使用第三方程序,如“蜻蜓FM”,就像闹钟可以定时自动开启。

如果是自己造,相当于重新编个程序出来,需要掌握大量专业性的东西,得不偿失

⑵ Android可以让主线程在其他子线程执行完后再执行吗如果可以,该怎么做

android中什么时候会选择用广播来进行线程间的通信 Android 多线程 通信 线程中通信就不要用广播了吧 进程中通信可以用广播或者aidl 可是,这两天看到的项目都是这么做的;然后,自己分析了下,觉得一下的理由也是可以成立的; 1.正常情况下我们选择handler消息机制来进行单向的线程间的通信;(工作线程向主线程发送消息) 因为主线程有现成的handler,而工作线程没有现成的handler,这样的话,主线程将handler交给工作线程而让工作线程将工作的结果交给主线程; 相反,工作线程中没有现成的handler(事实上是没有消息队列,也就是handler没有绑定到工作线程),那么,如果开辟的话,代码角度上是挺麻烦的(相对应广播机制来说); 2.广播机制本身就是双向的(工作线程向主线程发送广播,主线程向工作线程发送广播); //另外,对于像一个activity中通过fragment来进行界面的处理; 我们大多数情况下是采用广播的机制来实现fragment中adapter的数据的更新;这样做主要是考虑到工作线程的任务加载完成,而具体的对应刷新的activity可能还没有启动; 另外,基于接口隔离原则,如果用handler进行通信的话,则不能很好的满足这一原则; 你要是周期比较长 用广播好些吧 应该与周期关系不是很密切。最主要的原因是两条线成是双向通信。 Handler类似于P2P的通信。 广播则类似于一个server端,用来处理分发不同线程的请求,从控制器的角度来说用广播更好一点。 一般使用Handler的,多用于子线程处理事务,完成时告知主线程这一类的情况。 而类似楼主所说的多条线程之间需要频繁交互的话,广播是个很好的选择,并且结构清晰,只是不知道广播的性能与handler相比会怎么样。

⑶ 安卓关于handler和broadcast的问题

可以在Thread里面直接发送广播 依据Android开发文档中关于sendBroadcast方法的说明 http://developer.android.com/reference/android/content/Context.html#sendBroadcast(ndroid.content.Intent) 其中提到了是异步的 就是说明这册伍个发拿者送广播的方法最终是通过系统的线程来完成的 而且还可以参考这里所说的 http://stackoverflow.com/questions/11656763/is-it-ok-to-call-sendbroadcast-from-another-thread
至于消姿薯与使用Handler的方式来做有什么区别 可能我感觉到的就是一个是在worker线程中来完成 一个是在UI线程中来完成~

⑷ Android主线程到底是什么

  • Android中关于主线程的理解:

Android的主线程是UI线程,在Android中,四大组件运行在主线程中,在主线程中做耗时操作会导致程序出现卡顿甚至出现ANR异常,一个基本常识就是将耗时操作放到子线程中去处理,然后通过Handler回调到主线程。

  • 有三点还需要注意:

  1. 因为四大组件运行在一个主线程中,那么若果当前界面在显示的时候,后台的activity仍有处理逻辑再运行的话,仍然会造成当前界面的卡顿。

  2. 通过Handler回调到主线程只是避免程序出现ANR的第一步,必须要注意handler中逻辑处理的耗时,如果将很多消息都扔给了handler,那么也会给主线程造成压力,导致程序运行卡顿。

  3. 四大组件、Handler都是在一个线程中,那么主线程在同一时刻不可能发送两个广播,换句话说就是若果能够保证所有的广播都是在主线程中发送,那么广播内部其实不需要加上对异步操作的处理。

⑸ 简述在android中如何发送广播消息

1.发送广播
Intent intent = new Intent(BroadcastAction);
Bundle bundle = new Bundle();
bundle.putString("***", SUCCESS);
bundle.putString("FullPathName", mFullPathName);
intent.putExtras(bundle);
sendBroadcast(intent);
2.在Activity中创建一个内部类MyBroadcastReceiver扩展BroadcastReceiver,并在其中实现onReceive方法。
3.在Activity中声明一个MyBroadcastReceiver类型的成员变量,并注册:
private MyBroadcastReceiver myBroadcastReceiver;
...
myBroadcastReceiver = new MyBroadcastReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction(BroadcastAction);
registerReceiver(receiver, filter);
4.使用完后要记得释放
unregisterReceiver(receiver);

注:1和2中的 BroadcastAction要是同一个Action

⑹ 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中什么时候会选择用广播来进行线程间的通信 Android 多线程 通信

线程中通信就不要用广播了吧 进程中通信可以用广播或者aidl

可是,这两天看到的项目都是这么做的;然后,自己分析了下,觉得一下的理由也是可以成立的;

1.正常情况下我们选择handler消息机制来进行单向的线程间的通信;(工作线程向主线程发送消息)

因为主线程有现成的handler,而工作线程没有现成的handler,这样的话,主线程将handler交给工作线程而让工作线程将工作的结果交给主线程;

相反,工作线程中没有现成的handler(事实上是没有消息队列,也就是handler没有绑定到工作线程),那么,如果开辟的话,代码角度上是挺麻烦的(相对应广播机制来说);

2.广播机制本身就是双向的(工作线程向主线程发送广播,主线程向工作线程发送广播);

//另外,对于像一个activity中通过fragment来进行界面的处理; 我们大多数情况下是采用广播的机制来实现fragment中adapter的数据的更新;这样做主要是考虑到工作线程的任务加载完成,而具体的对应刷新的activity可能还没有启动;

另外,基于接口隔离原则,如果用handler进行通信的话,则不能很好的满足这一原则;

你要是周期比较长 用广播好些吧

应该与周期关系不是很密切。最主要的原因是两条线成是双向通信。

Handler类似于P2P的通信。
广播则类似于一个server端,用来处理分发不同线程的请求,从控制器的角度来说用广播更好一点。

一般使用Handler的,多用于子线程处理事务,完成时告知主线程这一类的情况。
而类似楼主所说的多条线程之间需要频繁交互的话,广播是个很好的选择,并且结构清晰,只是不知道广播的性能与handler相比会怎么样。

⑻ android怎么发送特定广播的

起一个线程,每发一个广播后就sleep一分钟,如此循环。(或者接受系统的timechanged这个广播,这个广播好像一分钟发一次)。

Android 在发送广播时的方法 sendBroadcast(Intent)。

①:Intent myIntent = new Intent();——【创建Intent对象】

②:myIntent.setAction(String)——【设置一般的要执行的动作。参数:动作一个动作的名称,如ACTION_VIEW。应用程序的具体行动,应与供应商的包名作为前缀。】

③:myIntent.putExtra(String,Object)——【广播中额外发送的数据,String为自定义key,Object表示多种数据类型】

④:sendBroadcast(myIntent);——【发送广播】

接收广播

Android在接收广播的方法是注册一个广播接收器 registerReceiver(MyReceiver,IntentFilter)。

①:首先创建MyReceiver类(类名自定义) 继承 BroadcastReceiver类。——【创建广播接收器】

②:在MyReceiver中重写public void onReceive(Context context, Intent intent)方法。这个方法在接收到广播后触发。——【重写处理方法】

③:在Activity或者Service启动时 onCreate()、onStartCommand()等方法中实例化 MyReceiver类——【启动时实例化广播接收器】

④:IntentFilter filter = new IntentFilter();——【创建IntentFilter对象 意图过滤器】

⑤:filter.addAction(String);——【在过滤器中加入过滤条件,说明接收什么广播】

⑥:registerReceiver(cmdReceiver, filter);——【注册广播,参数为(广播接收器,意图过滤器)】

⑼ android 怎样发送广播更新ui

更新ui 可以直接在主线程里操作。一般用不到广播。如果非要用广播,一般都是服务更新线程才这么做。在服务里注册/发送广播。然后在ui线程里接受广播,执行更新操作。

⑽ Android高效安全的本地广播LocalBroadcast完全解析

广播作为Android 四大组件有非常广泛的用途。广播可以用作进程间通信,也会用作进程内部某些组件内消息的传递。
这就会有个问题,如果想让发送的广播只有我自己能收到,不想被别人劫持到,来获取到广播中的敏感信息。
另外其他人如果发送相同Action的广播来伪造真正的广播,就会欺骗我的receiver.

如何安全高效的实现进程内部的广播发送呢?
有人说可以使用给广播加权限啊,你可以在Intent中指定PackageName 啊,后面的文章详解,先简单看下:

当然这都是书上告诉我们的方式,但是我感觉还不够简单。当然经过一番配置你可以实现了。
好了,现在安全解决了,那高效呢?

我们翻看context.sendBroadcast源码,看到发送广播的流程真的是相当的复杂啊。曾经天真年少的我竟然幻想一天弄懂广播的整个过程,但当我看到sendBroadcast方法的行数时我脸上是大写的崩溃。暂且不谈广播队列的分发规则和过程。这中间是存在的两次binder call就让这个过程变的不是那么高效。
首先你sendBroadcast会把广播信息告诉System_server (第一次Binder call),然后system_server经过一番查看找到你要的receivers,然后进入分发队列等待分发(过程很复杂),然后调用APP进程receiver的onReceiver()方法(第二次Binder call).大昌纯物兄弟,我明明只想在我的进程内部发送一个广播在进程内部接收,为啥还要通过system_server呢。就算你长得帅,你有Free style,可是你很忙啊,找你的人那么多。自己的事情自己做,这是小学了老师经常教导我们的。看来Google的程序员一直没有忘记小学老师的教诲:

看,迈着整齐步伐雄赳赳气昂昂向我们走来的是LocalBroadcast:
先来看官方说明:

意思就是这个很牛裤做逼,和全局广播相比有很多数不清的优势。(看来实现这个的哥们和实现全局广播的哥们关系不大好,竟然用这个词语: has a number of advantages) 。

我们下面来看下LocalBroadcastManager的源码:
https://android.googlesource.com/platform/frameworks/support/+/android-support-lib-19.1.0/v4/java/android/support/v4/content/LocalBroadcastManager.java

1.先来看下LocalBroadcastManager的构造,是使用标准的单例模式实现的。
APP开发者拿到mInstance之后就可以调用registerReceiver、unregisterReceiver、sendBroadcast。

看到构造函数中没有做复杂的操作,在主线程初始化了一个Handler.
可以猜测到这个Handler正是用于对广播的分发。

2.广播的注册、反注册、发送流程
如果让我们来自己来实现广播的注册、反注册、发送我们会怎么搞呢?
首先,注册的时候需要提供BroadcastReceiver和对应的IntentFilter,我们可以对这种数据结构进行封装,放到一个类中ReceiverRecord。
然后维护一个ReceiverRecord对象列表,用于记录当前注册了哪些BroadcastReceiver。可以简单使用ArrayList<ReceiverRecord>.
在unRegister的时候根据提供的BroadcastReceiver对象,遍历List找出对应的receiver进行移除。
这样每来一个unRegister我们都需要对Receiver列表做一次遍历,耐液开销有点大,在查操作比较多的时候我们可以使用MAP。
HashMap<BroadCastReceiver, ReceiverRecord>
ReceiverRecord中已经包含BroadcastReceiver对象了,所以value直接使用IntentFilte就行了,简化数据结构。
那如果一个Receiver注册了多个IntentFilter呢?比如说一个receiver对象注册两次传入不同的IntentFilter.所以Value需要改造为ArrayList<IntentFilter>。 最终用于维护当前Reciver对象列表的数据结构是这样事儿的:
HashMap<BroadcastReceiver, ArrayList<IntentFilter>> mReceivers .
当删除时可以通过receiver对象为key在map中快速查找并移除。

发送广播的时候呢?我们知道sendBroadcast时只传入了Intent对象,Intent携带了Action用于和已经注册的receiver匹配。在查找receiver时,需要对 HashMap<BroadcastReceiver, ArrayList<IntentFilter>> mReceivers 的Value进行遍历,每一个Value ArrayList<IntentFilter> 又需要遍历一次。这个查找的开销实在太大了。
看来我们为了实现Action和receiver的快速匹配需要再维护一个数据结构了。同样是频繁查找的需求使用HashMap.
将Action作为Key,value肯定是与之匹配的receiver了。因为一个Action可能会对应多个receiver,receiver注册的时候可以使用相同的Action.所以value需要使用ArrayList<BroadcastReceiver>. 当发送广播时可以快速根据Action找到对应的receiver。对了,不仅仅要使用Action匹配,filter中还有其他信息匹配成功之后才能确认是真正的receiver.所以需要使用ReceiverRecord作为value,因为不仅包含了receiver对象,同时包含了IntentFilter.所以最终的数据结构是 HashMap<String,ArrayList<ReceiverRecord>>.

我们来看Google是怎么实现的呢?

先来看两个内部类:

再来看几个成员变量:

广播的发送过程

广播的反注册过程

可以看到最终把要发送的广播加入队列mPendingBroadcasts,然后使用Handler发送消息给主线程处理的,调用executePendingBroadcasts()进行分发。

LocalBroadcast也支持使用同步的方式进行分发:

1.LocalBroadcast是APP内部维护的一套广播机制,有很高的安全性和高效性。
所以如果有APP内部发送、接收广播的需要应该使用LocalBroadcast。
2.Receiver只允许动态注册,不允许在Manifest中注册。
3.LocalBroadcastManager所发送的广播action,只能与注册到LocalBroadcastManager中BroadcastReceiver产生互动。

热点内容
获取数据库所有表 发布:2025-07-05 09:39:12 浏览:650
wcfphp 发布:2025-07-05 09:39:07 浏览:174
解压密码对 发布:2025-07-05 09:33:00 浏览:585
广东金税盘的服务器地址是什么 发布:2025-07-05 09:10:29 浏览:703
挂式手机卡的服务密码是多少 发布:2025-07-05 08:57:40 浏览:943
电信卡密码八位数是多少 发布:2025-07-05 08:49:37 浏览:440
配置高用的久选什么电脑 发布:2025-07-05 08:22:40 浏览:741
迷你世界如何卡进设密码的房间 发布:2025-07-05 08:15:16 浏览:882
小米9se买哪个配置 发布:2025-07-05 07:57:32 浏览:364
金山快盘拒绝访问 发布:2025-07-05 07:42:29 浏览:251