ImageVerifierCode 换一换
格式:DOCX , 页数:43 ,大小:355.01KB ,
资源ID:27027506      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/27027506.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(Android 70 ActivityManagerService5 广播Broadcast相关流程分析2.docx)为本站会员(b****3)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

Android 70 ActivityManagerService5 广播Broadcast相关流程分析2.docx

1、Android 70 ActivityManagerService5 广播Broadcast相关流程分析2Android 7.0 ActivityManagerService(5) 广播(Broadcast)相关流程分析(2)4 broadcastIntentLocked函数Part IV./ Merge into one list.int ir = 0;if (receivers != null) / A special case for PACKAGE_ADDED: do not allow the package / being added to see this broadcast.

2、This prevents them from / using this as a back door to get run as soon as they are / installed. Maybe in the future we want to have a special install / broadcast or such for apps, but wed like to deliberately make / this decision. /处理特殊的Action,例如PACKAGE_ADDED,系统不希望有些应用一安装就能启动 /APP安装后,PKMS将发送PACKAGE_

3、ADDED广播 /若没有这个限制,在刚安装的APP内部静态注册监听该消息的BroadcastReceiver,新安装的APP就能直接启动 String skipPackages = null; if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction() | Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction() | Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction() Uri data = intent.getD

4、ata(); if (data != null) String pkgName = data.getSchemeSpecificPart(); if (pkgName != null) skipPackages = new String pkgName ; else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction() skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); if (skipPack

5、ages != null & (skipPackages.length 0) for (String skipPackage : skipPackages) if (skipPackage != null) int NT = receivers.size(); for (int it=0; itNT; it+) ResolveInfo curt = (ResolveInfo)receivers.get(it); if (curt.activityInfo.packageName.equals(skipPackage) /将skipPackages对应的BroadcastReceiver移出re

6、ceivers receivers.remove(it); it-; NT-; int NT = receivers != null ? receivers.size() : 0; int it = 0; ResolveInfo curt = null; BroadcastFilter curr = null; /NT对应的是静态BroadcastReceiver的数量 /NR对应的是动态BroadcastReceiver的数量 /若发送的是无序广播,此时NR为0 /若是有序广播,才会进入下面两个while循环 /下面两个while循环就是将静态注册的BroadcastReceiver和动态注

7、册的BroadcastReceiver /按照优先级合并到一起(有序广播才会合并) while (it NT & ir = curt.priority) / Insert this broadcast record into the final list. receivers.add(it, curr); ir+; curr = null; it+; NT+; else / Skip to the next ResolveInfo in the final list. it+; curt = null; while (ir 0) | resultTo != null) BroadcastQue

8、ue queue = broadcastQueueForIntent(intent); /构造对应的BroadcastRecord BroadcastRecord r = new BroadcastRecord(.); . /同样判断是否需要替换,这里是Ordered Queue boolean replaced = replacePending & queue.replaceOrderedBroadcastLocked(r); if (!replaced) /没替换时,就加入Ordered Queue queue.enqueueOrderedBroadcastLocked(r); /触发发送

9、流程 queue.scheduleBroadcastsLocked(); else / There was nobody interested in the broadcast, but we still want to record / that it happened. if (intent.getComponent() = null & intent.getPackage() = null & (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) = 0) / This was an implicit broadcast. le

10、ts record it for posterity. /没有处理的静态或有序广播,保存起来 /感觉保存起来也没什么用啊 addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0); .简单来说,broadcastIntentLocked的第四部分工作就是为有序广播和静态广播,构造对应的BroadcastRecord(按优先级顺序), 然后将BroadcastRecord加入到Ordered Queue中,并触发广播发送流程。至此,整个broadcastIntentLocked函数分析完毕,除去一些条件判断的细节外,整个

11、工作流程如下图所示:1、处理粘性广播。 由于粘性广播的特性(BroadcastReceiver注册即可接收),系统必须首先保存粘性广播。2、处理普通动态广播。 普通广播是并发的,系统优先为动态注册的BroadcastReceiver发送广播。 动态广播对应的BroadcastRecord加入到Parallel Queue中。3、处理静态广播和有序广播。 这一步主要是为静态注册的BroadcastReceiver发送广播,对应的BroadcastRecord加入到Ordered Queue中。此外,需要注意的是: 如果广播是有序的,那么第2步不会为动态注册的BroadcastReceiver发送

12、广播,而是在第3步统一发送。 发送有序广播时,AMS将按照BroadcastReceiver的优先级,依次构造BroadcastRecord加入到Ordered Queue中。四、BroadcastQueue的scheduleBroadcastsLocked函数流程分析 从上面的代码,我们知道广播发送方调用sendBroadcast后,AMS会构造对应的BroadcastRecord加入到BroadcastQueue中, 然后调用BroadcastQueue的scheduleBroadcastsLocked函数。现在,我们就来看一下scheduleBroadcastsLocked相关的流程。p

13、ublic void scheduleBroadcastsLocked() . /避免短时间内重复发送BROADCAST_INTENT_MSG if (mBroadcastsScheduled) return; mHandler.sendMessage(mHandler.obtainMessage(BROADCAST_INTENT_MSG, this); mBroadcastsScheduled = true;上面的代码将发送BROADCAST_INTENT_MSG,触发BroadcastQueue调用processNextBroadcast进行处理。 processNextBroadcast

14、函数同样非常的长,大概有500多行。我们还是分段进行分析。1 processNextBroadcast函数Part Ifinal void processNextBroadcast(boolean fromMsg) synchronized(mService) BroadcastRecord r; . /更新CPU的使用情况 /处理静态广播时,可能需要拉起对应进程,因此在这里先记录一下CPU情况 mService.updateCpuStats(); if (fromMsg) /处理BROADCAST_INTENT_MSG后,将mBroadcastsScheduled置为false /sched

15、uleBroadcastsLocked就可以再次被调用了 mBroadcastsScheduled = false; / First, deliver any non-serialized broadcasts right away. /先处理“并发”发送的普通广播 while (mParallelBroadcasts.size() 0) /依次取出BroadcastRecord r = mParallelBroadcasts.remove(0); /记录发送的时间 r.dispatchTime = SystemClock.uptimeMillis(); r.dispatchClockTime

16、 = System.currentTimeMillis(); final int N = r.receivers.size(); . for (int i=0; i 0) for (int i = 0; i r.requiredPermissions.length; i+) String requiredPermission = r.requiredPermissionsi; int perm = mService.checkComponentPermission(requiredPermission, filter.receiverList.pid, filter.receiverList.

17、uid, -1, true); if (perm != PackageManager.PERMISSION_GRANTED) . /只要一条权限不满足,就结束 skip = true; break; /进一步检查权限的合理性 int appOp = AppOpsManager.permissionToOpCode(requiredPermission); if (appOp != AppOpsManager.OP_NONE & appOp != r.appOp & mService.mAppOpsService.noteOperation(appOp, filter.receiverList.

18、uid, filter.packageName) != AppOpsManager.MODE_ALLOWED) . skip = true; break; /这段代码我看的有些懵逼,发送方没要求权限,还检查啥? if (!skip & (r.requiredPermissions = null | r.requiredPermissions.length = 0) int perm = mService.checkComponentPermission(null, filter.receiverList.pid, filter.receiverList.uid, -1, true); if (

19、perm != PackageManager.PERMISSION_GRANTED) . skip = true; /还有一些其它的检查,不再分析代码了。 /包括是否允许以background的方式发送、IntentFirewall是否允许广播中的Intent发送 . if (skip) /不满足发送条件的话,标记一下,结束发送 r.deliveryindex = BroadcastRecord.DELIVERY_SKIPPED; return; / If permissions need a review before any of the app components can run, w

20、e drop / the broadcast and if the calling app is in the foreground and the broadcast is / explicit we launch the review UI passing it a pending intent to send the skipped / broadcast. /特殊情况,还需要再次检查权限,中断广播发送 /再次满足发送条件后,会重新进入到后续的发送流程 if (Build.PERMISSIONS_REVIEW_REQUIRED) if (!requestStartTargetPermis

21、sionsReviewIfNeededLocked(r, filter.packageName, filter.owningUserId) r.deliveryindex = BroadcastRecord.DELIVERY_SKIPPED; return; /可以发送了,标记一下 r.deliveryindex = BroadcastRecord.DELIVERY_DELIVERED; / If this is not being sent as an ordered broadcast, then we / dont want to touch the fields that keep t

22、rack of the current / state of ordered broadcasts. if (ordered) /如果发送的是有序广播,则记录一些状态信息等,不涉及广播发送的过程 . try . /若BroadcastReceiver对应的进程处于fullBackup状态(备份和恢复),则不发送广播 if (filter.receiverList.app != null & filter.receiverList.app.inFullBackup) if (ordered) /有序广播必须处理完一个,才能处理下一个,因此这里主动触发一下 skipReceiverLocked(r

23、); else /执行发送工作 performReceiveLocked(.); if (ordered) r.state = BroadcastRecord.CALL_DONE_RECEIVE; catch (RemoteException e) . deliverToRegisteredReceiverLocked看起来很长,但大部分内容都是进行权限检查等操作,实际的发送工作交给了performReceiveLocked函数。 广播是一种可以携带数据的跨进程、跨APP通信机制,为了避免安全泄露的问题,Android才在此处使用了大量的篇幅进行权限检查的工作。在这一部分的最后,我们跟进一下p

24、erformReceiveLocked函数:void performReceiveLocked(.) / Send the intent to the receiver asynchronously using one-way binder calls. if (app != null) if (app.thread != null) / If we have an app thread, do the call through that so it is / correctly ordered with other one-way calls. try /通过Binder通信,将广播信息发往BroadcastReceiver处在的进程 app.thread.scheduleRegisteredReceiver(.); catch (RemoteException ex) / Failed to call into the

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1