您的位置:首页 > 移动开发 > Android开发

《深入理解 Android》笔记:ActivityManagerService

2016-09-24 16:38 726 查看

《深入理解 Android》笔记:ActivityManagerService

时间 2015-04-15 02:41:43
RincLiu

原文  http://rincliu.com/blog/2015/04/14/android-framework-ams/ 主题
安卓开发

ActivityManagerService 概述:

ActivityManagerService
负责四大组件的启动/切换/调度、进程的管理/调度等;

ActivityManagerService
继承自
ActivityManagerNative
类,并实现了
Watchdog.Monitor
BatteryStatsImpl.BatteryCallback
接口;而
ActivityManagerNative
继承自
Binder
类,并实现了
IActivityManager
接口;

客户端使用的是
ActivityManager
类,其内部通过调用
ActivityManagerNative.getDefault()
得到一个
ActivityManagerProxy
对象,通过它与
ActivityManagerService
通信;

system_server 对 ActivityManagerService 的初始化:

调用
ActivityManagerService.main()
方法,返回
Context
对象;

调用
ActivityManagerService.setSytemProcess()
,将
system_server
进程加入
ActivityManagerService
,便于后者管理;

调用
ActivityManagerService.installSystemproviders()
,将
SettingsProvider
放到
system_server
进程中运行;

调用
ActivityManagerService.self().setWindowManager()
,在内部保存
WindowManagerService


调用
ActivityManagerNative.getDefault().showBootMessage()
,显示启动信息;

调用
ActivityManagerService.self().systemReady()
,在传入的
Runnable
对象的
run()
方法中:

调用
startSystemUi()
,启动系统 UI;

调用 Battery、Network 等模块的
systemReady()


启动
Watchdog


ActivityManagerService::main():

创建
AThread
线程对象:

设置线程优先级为
THREAD_PRIORITY_FOREGROUND


创建
ActivityManagerServive
对象:

创建 /data/system/ 目录;

创建
BatteryStatsService
UsageStatsService


读取 OpenGL、及资源配置信息
Configuration


读取并解析 /proc/stat 文件中的 CPU 和内存信息、/data/system/packages-compact.xml 文件中的需要考虑屏幕尺寸的 APK 信息;

调用
Watchdog.getInstance().addMonitor()
将自己加入监控;

创建
mProcessStatsThread
线程,用于定时更新系统信息,和
mProcessStats
交互;

调用
ActivityThread.systemMain()
方法返回
ActivityThread
对象:

调用
HardwareRenderer.disable(true)
禁用硬件渲染;

创建
ActivityThread
对象,并调用其
attach(true)
方法,

调用
ActivityThread.getSystemContext()
得到
Context
对象;

创建用于管理
Activity
启动和调度的核心类
ActivityStack
对象;

调用
BatteryStatsService
UsageStatsService

publish()
方法;

调用
ActivityManagerService.startRunning()
,主要调用
systemReady()


ActivityThread:

ActivityThread
代表一个应用进程的主线程(其
main
方法由所在进程的主线程执行),其职责为调度和执行运行在主线程的四大组件;

通过
ActivityThread
可以把 Android 系统提供的组件之间的交互机制和接口(如
Context
)也扩展到
system_server
中使用;实际上
system_server
可以看作一个特殊的应用进程(framework-res.apk 和 SettingsProvider.apk 都运行在该进程中);

attach(true)
对系统进程的处理:

创建
Instrumentation
工具类对象,它通过 AndroidManifest.xml 中的标签描述,用于监控与其他组件的交互;

创建
ContextImpl
对象,并调用其
init()
方法;
Context
是一个可以操作
Application
及其中四大组件的接口;

调用
Instrumentation.newApplication()
创建
Application
对象;它是可以看作一个四大组件的容器,
ActivityManagerService
内部通过
mAllApplications
保存所有
Application


调用
Application.onCreate()


调用
ViewRootImpl.addConfigCallback()
,响应
onConfigurationChanged()
onLowMemory()
onTrimMemory()
等方法;

getSystemContext()


调用
ContextImpl.createSystemContext()
创建
ContextImpl
对象;

创建
LoadedApk
对象,传入的
package
参数为
"android"
,即代表 framework-res.apk,相当于读取系统资源;

调用
ContextImpl.init()
方法,并传入上面的
LoadedApk
对象,相当于加载系统资源;

调用
ContextImpl.getResources().updateConfiguration()
,初始化屏幕等配置信息;

IApplicationThread 和 ActivityThread:

IApplication
定义了
ActivityManagerService
和其他应用进程进行
Binder
通信的接口:
scheduleLaunchActivity()
schedulePauseActivity()

scheduleStopActivity()
等;

ActivityThread
通过成员变量
mAppThread
指向其内部类
ApplicationThread
,而它继承自
IApplicationThread
的实现类
ApplicationThreadNative


ActivityManagerService
通过
IApplication
定义的接口向
ActivityThread
所在线程发消息,进而控制
Activity
执行相关回调;

Context 家族:

Context
: 抽象类,提供了一组通用的 API;

ContextIml
: 实现了
Context
类的功能, 大部分功能都是直接调用其属性
mPackageInfo
去完成;

ContextWrapper
: 对
Context
类的包装,该类的构造函数包含一个的
Context
引用,即
ContextIml
对象;

ContextThemeWrapper
: 该类内部包含 Theme 相关的接口,即
android:theme
属性指定的。只有
Activity
需要主题,
Service
Application
不需要主题,所以
Service
/
Application
直接继承于
ContextWrapper
类;

Context
实例个数 =
Service
个数 +
Activity
个数 + 1(
Application
对应的
Context
实例);

ActivityManagerService::setSystemProcess():

调用
ServiceManager.addService()
注册几个服务:

ActivityManagerService


MemBinder
:用于打印内存信息;

GraphicsBinder
:用于输出应用进程使用硬件显示加速的信息,Android 4.0 新增的服务;

CpuBinder
:CPU 信息;

PermissionController
:权限管理服务;

调用
context.getPackageManager().getApplicationInfo()
查询包名为
android
ApplicationInfo
对象;

调用
ActivityThread.installSystemApplicationInfo()
注册上面查询到的
ApplicationInfo
对象:

调用
ActivityThread.getSystemContext()
返回之前初始化过的
Context
对象;

调用
context.init(new LoadedApk())
再次初始化;注意之前初始化传入的最后一个参数为
null
,这次传入的是上面查询到的包名为
android
ApplicationInfo
对象;

创建
Profiler
对象,用于性能统计;

调用
ActivityManagerService.newProcessRecordLocked()
创建用于保存进程信息的
ProcessRecord
对象:

获取
BatteryStatsService
对象,并创建一个耗电量统计项;

创建
ProcessRecord
对象:

初始化
BatteryStatsService
ApplicationInfo

ProcessName
IApplicationThread
等成员变量;

初始化
maxAdj
hiddenAdj
curRawAdj
curAdj
等和进程调度和内存管理相关的变量;

对于
system_server
进程,
ActivityManagerService
还进行了特殊处理:

将其
persisten
设为
true
,被 kill 后会重建;

pid
设为
MY_PID
,即
system_server
进程号;

processName
设置为
system


maxAdj
设置为最大值
SYSTEM_ADJ


ActivityManagerService
内部通过
mProcessNames
保存所有进程名,调用
put()
保存上面创建的
ProcessRecord


调用
ActivityManagerService.updateLruProcessLocked()
,根据系统当前状态调整进程调度优先级和 OOM_Adj;

ActivityManagerService::installSystemProviders():

mProcessNames
取出 processName 为
system
且 uid 为
SYSTEM_UID
ProcessRecord
,即
system_server
对应的进程;

调用
ActivityManagerService.generateApplicationProvidersLocked()
返回
List<ProviderInfo>
对象:

根据进程名和 uid,调用
PackageManagerService.queryContentProviders()
查询符合条件的
List<ProviderIndo>


遍历
List<ProviderInfo>
根据包名和
ApplicationInfo
查询(如果不存在则构造)并保存
ContentProviderRecord


调用
ensurePackageDexOpt()
执行 dex 优化;

providers
中去除非系统 Provider;

调用
ActivityThread.installSystemProviders()
,将
providers
安装到
system_server
进程:

调用
installProvider()
得到一个
IContentProvider
对象;

找到
Provider
对应的
Context
,并调用
Context.getClassLoader()
、通过反射生成
ContentProvider
实例;

调用
IContentProvider.asBinder.linkToDeath()


创建
ProviderClientRecord
对象,并保存到
mLocalProviders


创建
ContentProviderRefCount
对象对
ContentProvider
进行引用计数控制,引用数为 0 则从系统注销;

调用
ActivityManagerService.publishContentProviders()


根据调用者的 pid 找到对应的
ProcessRecord


ProcessRecord
pubProviders
中找到对应的
ContentProviderRecord
,如果找到则以 authority 为 key 保存;

移除
mLaunchingProviders
中保存的处于启动状态的 Provider,并调用
notifyAll()
通知等待它们启动的进程;

调用
updateOomAdjLocked()
调整 oom_adj;

创建
CoreSettingsObserver
对象,监听 Settings 数据库 secure 表的变化;

调用
UsageStatsService.monitorPackages()


ContentProvider:

ContentProvider
本身只是一个容器,跨进程调用的支持是通过
Transport
实现的;
Transpor
Binder
的子类
ContentProviderNative
派生;

ContentProviderNative
实现了
IContentProvider
接口,其内部类
ContentProviderProxy
供客户端使用;

ContentProvider
getIContentProvider()
返回
Transport
对象;

系统提供 ComponentName 和 authority 两种方式找到
ContentProvider
,所以
ActivityManagerService
存在对应的两个变量:
mProvidersByClass
mProvidersByName


ContentProviderRecord:

ContentProviderRecord
继承自
ContentProviderHolder
,内部保存了
ProviderInfo
、该 Provider 驻留进程的
ProcessRecord
、以及使用该 Provider 的客户端所在进程的
ProcessRecord


ActivityManagerService
mProviderByClass
成员和
ProcessRecord
pubProviders
成员均以 ComponentName 为 key 来保存对应的
ContentProviderRecord


ProviderClientRecord:

ProviderClientRecord
ActivityThread
提供的用于保存
ContentProvider
信息的结构;

内部主要成员:

mLocalProvider
用于保存
ContentProvider
对象;

mProvider
用于保存
IContentProvider
对象(即
Transport
对象);

mName
用于保存该
ContentProvider
的一个 authority;

ActivityManagerService::systemReady():

准备
PRE_BOOT_COMPLETED
广播,向
PackageManagerService
查询接收者,为最后一个接收者注册回调(用来显示启动消息等),最后发送广播;

杀掉那些在
ActivityManagerService
还未启动完成就已经先启动的应用进程(一般 Native 进程是不会向它注册的);

从 Settings 数据库获取配置信息:

debug_app
: 需要 debug 的 APP 名称;

wait_for_debugger
:表示需要等待调试器,否则直接启动;

always_finish_activities
: 当一个
Activity
不再有地方使用时是否立即执行 destroy;

font_scale
: 控制字体放大倍数(Android 4.0 新增);

调用传入的
Runnable
类型的
goingCallback
参数的
run()


调用
startSystemUi()
,启动
SystemUIService
(实现了系统状态栏);

调用 Battery、Network 等其他模块的
systemReady()
,启动
Watchdog


启动
persistent
为的 APK 进程(排除掉包名为
android
的 framework-res.apk,因为它之前已经被启动);

调用
startHomeActivityLocked()
启动 Home 界面;

调用
finishBooting()


注册 PACKAGE_RESTART 的
BroadcastReceiver
处理包重启;

启动那些等待启动的进程;

每隔 15 分钟检查一次各应用进程用电情况,杀掉使用
Wakelock
时间过长的进程;

调用
SytemProperties.set()
设置
sys.boot_completed
属性为;

发送
ACTION_BOOT_COMPLETED
广播;

ActivityStack、ActivityRecord、TaskRecord:

ActivityRecord
task
变量指向该
Activity
所在的 Task;
state
变量表示
Activity
状态;

ActivityStack
mMainStack
表示是否是主 Stack,由于目前只有一个
ActivityStack
,所以该变量值为
true


ActivityStack
mHistory
成员是
ArrayList
类型,用于保存系统中所有
ActivityRecord


ActivityStack
没有变量保存所有
TaskRecord


ActivityStack::startActivityMayWait():

PackageManagerService
查询匹配传入的
Intent

ActivityInfo


获取
Binder
调用方 uid 和 pid;

调用
startActivityLocked()
返回启动结果
res


如果调用者不为空,则调用
ActivityManagerService.getRecordForAppLocked()
得到它的
ProcessRecord
;如果
ProcessRecord
为空(该进程没有在
ActivityManagerService
注册),则返回
START_PERMISSION_DENIED
错误;

声明两个
ActivityRecord
类型的变量
sourceRecord
(启动目标
Activity
的那个
Activity
)和
resultRecord
(接收启动结果的
Activity
,即处理
onActivityResult
Activity
);一般情况下,二者指向同一个
Activity


读取
Intent
flags
,检查
err
是否为,检查权限信息;

ActivityManagerService
设置一个
IActivityController
类型的监听者(主要用于 Monkey 测试);

创建
ActivityRecord
对象;

调用
ActivityManagerService.checkAppSwitchAllowedLocked()
检查调用建成是否有权限切换应用,如果没有权限,则保存到
ActivityManagerService
mPendingActivityLaunches
变量;

调用
ActivityManagerService.doPendingActivityLaunchesLocked()
启动处于 pending 状态的
Activity


调用
startActivityUncheckedLocked()
完成本次启动请求;

如果
Configuration
有变化,调用
ActivityManagerService.updateConfigurationLocked()


处理启动结果;

ActivityStack::startActivityUncheckedLocked():

判断是否需要创建新的 Task,以下两种情况需要在
Intent
flags
附加
Intent.FLAG_ACTIVITY_NEW_TASK


发起请求的
sourceRecord
为空,或者为单例(独占一个 Task);

待启动的
Activity
设置了
SingleTask
SingleInstance


调用
findTaskLocked()
findActivityLocked()

mHistory
中得到
ActivityRecord
类型的
taskTop
对象;

调用
topRunningNonDelayedActivityLocked()
判断是否处于栈顶,决定是否创建新的
Activity


ActivityRecord
设置
TaskRecord


调用
ActivityManagerService.grantUriPermissionFromIntentLocked()
授权;

调用
stackActivityLocked()
完成启动:

如果不是新 Task,则从
mHistory
中找到对应的
ActivityRecord
位置;否则,将其添加到
mHistory
末尾;

设置
ActivityRecord
inHistory

true
,表示已经存在与
mHistory
中;

判断是否显示
Activity
切换动画,需要与
WindowManagerService
交互;

调用
resumeTopActivityLocked()


ActivityStack::resumeTopActivityLocked():

调用
topRunningActivityLocked()
mHistory
中找到第一个需要启动的
ActivityRecord
,如果没有则启动 Home 页面;

将该
ActivityRecord
mStoppingActivities

mGoingToSleepActivities
mWaitingVisibleActivities
中移除;

如果当前正在 pause 一个
Activity
,需要先等待 pause 完毕,然后系统重新调用
resumeTopActivityLocked()


mResumedActivity
指向上次启动的
Activity
,即当前显示的
Activity
;如果它不为空,调用
startPausingLocked()
中止,并返回;

如果传入的
prev
页面不为空,则需要通知
WindowManagerService
进行与页面切换相关的工作(停止绘制等);

如果该
ActivityRecord
对应的进程已存在,则只需要重启该
Activity


如果不存在,通知
WindowManagerService
显示启动页面,并调用
startSpecificActivityLocked()
:

调用
ActivityManagerService.getProcessRecordLocked()
根据进程名和uid查找进程;

设置启动时间等信息;

如果该进程存在,并已经向
ActivityManagerService
注册,调用
realStartActivityLocked()
启动目标
Activity


如果该进程不存在,调用
ActivityManagerService.satrtProcessLocked()
启动进程;

ActivityManagerService::startProcessLocked():

处理
FLAG_FROM_BACKGROUND
标志和
BadProcess


一个进程如果连续崩溃超过两次,
ActivityManagerService
会将其
ProcessRecord
加入
mBadProcesses


由于进程崩溃会弹框,所以一般禁止启动处于后台的 BadProcess;但如果是用户触发的(比如点击 button 跳到后台页面),则会把该进程从
mBadProcesses
移除,给它“重新做人”的机会;

创建
ProcessRecord
对象,并保存到
mProcessNames


mProcessesOnHold
移除该
ProcessRecord
,它用于保存在系统还未准备好就发送启动请求的
ProcessRecord


更新 CPU 信息,从
PackageManagerService
查询该进程的 gid;

调用
Process.start()
,让 Zygote 派生子进程,该子进程执行
ActivityThread.main()
:

调用
Process.setArgV0()
设置进程名为
pre-initialized


创建
ActivityThread
对象;

调用
ActivityThread.attach(false)
处理应用进程:

设置在
DropBoxManagerService
日志系统中看到的进程名为
pre-initialized


调用
RuntimeInit.setApplicationObject(mAppThread.asBinder())


调用
ActivityManagerService.attachApplicationLocked(mAppThread)


执行电量统计;

如果该进程为
persistent
,通知
Watchdog


以 pid 为 key,将该进程的
ProcessRecord
保存到
mPidsSelfLocked


发送
PROC_START_TIMEOUT_MSG
消息,如果新进程 10s 没有和
ActivityManagerService
交互,则认为新进程启动失败;

ActivityManagerService::attachApplicationLocked():

根据
pid
查找对应的
ProcessRecord
;如果为空(未向
ActivityManagerService
注册):

如果
pid
大于 0 且不是
system_server
进程,调用
Process.killProcessQuiet()
杀掉该进程;

否则调用
IApplicationThread.sheduleExit()
退出;

如果该
ProcessRecord.thread
对象不为空,表示该进程为旧的未被杀死的进程,系统不会重用,而是调用
handleAppDiedLocked()
处理;

创建应用死亡讣告对象
AppDeathRecipient
,并调用
thread.asBinder().linkToDeath()


设置该进程的调度优先级以及 oom_adj 相关变量;

通过
PackageManagerService
查询运行在该进程中的
ContentProvider
对象;

对相关 Package 进行 Dex 优化;

调用
ApplicationThread.bindApplication()


调用
ServiceManager.initServiceCache()
保存
ActivityManagerService
传递过来的
Service
信息;

调用
setCoreSettings()
向主线程消息队列添加
SET_CORE_SETTINGS
消息;

创建
AppBindData
对象,用于保存
processName

appInfo
等参数信息;

初始化性能统计对象
Profiler


调用
Process.setArgV0()
DdmHandleAppName.setAppname()
设置正式进程名;

对于 persistent 进程,在低内存设备上,调用
HardwareRenderer.disable(false)
禁用硬件加速;

初始化
AsyncTask
的线程池;

设置时区、语言、资源、兼容模式;

根据传过来的
ApplicationInfo
创建一个对应的
LoadedApk
对象;

StrictMode 和 DebugMode 相关处理;

设置 HTTP 代理信息;

如果 Package 声明了
FLAG_LARGE_HEAP
,调用
VMRuntime.getRuntime().clearGrowthLimit()
清除内存限制;

根据
LoadedApk
对象,并利用反射,生成 Manifest 文件中声明的
Application
对象;用
mInitialApplication
保存该进程中创建的第一个
Application


调用
installContentProviders()
安装本 Package 下的
ContentProvider


调用
mInstrumentation.callApplicationOnCreate()
执行
Application
对象的
onCreate()
方法;

调用
updateLruProcessLocked()


调用
ActivityStack.topRunningActivitylLocked()
获取
ActivityStack
中的第一个需要运行的
ActivityRecord


根据
processName
uid
确定该
ActivityRecord
和目标进程有关,否则调用
ActivityStack.ensureActivitiesVisibleLocked()
处理;

调用
ActivityStack.realStartActivityLocked()
启动该
ActivityRecord


对于
mPendingServices
中处于 pending 状态的
ServiceRecord


如果根据
processName
uid
判断和目标进程无关,则不作处理;

否则调用
realStartService()
启动该
ServiceRecord


如果上面几个组件初始化有错误,调用
handleAppDiedLocked()
处理;

调用
updateOomAdjLocked()
根据该进程中的组建情况调节 oom_adj 值(组件越多越不易被杀死回收);

ActivityStack::realStartActivityLocked():

调用
ActivityManagerService.updateConfigurationLocked()
处理 Config 变化;

ActivityRecord
加入到
ProcessRecord

activities
中保存;

调用
ActivityManagerService.updateLruProcessLocked()
更新进程优先级;

调用
ProcessRecord.thread
ActivityThread
类型)的
scheduleLaunchActivity()
通知应用的主进程启动
Activity
:

调用
performLaunchActivity()
:

通过反射机制创建目标
Activity
对象;

调用
Activity
onCreate()
onStart()
方法;

调用
handleResumeActivity()


调用
performResumeActivity()
执行
Activity

onResume()
方法;

将上面完成
onResume()
Activity
保存到
mNewActivities
中;

调用
Looper.myQueue().addIdleHandler()
向消息队列添加一个
Idler
对象:

MessageQueue
对 Idle 消息会最后处理;

这里的
Idler
对象内部会调用
ActivityManagerService.activityIdle()


如果启动失败,调用
ActivityManagerService.finishActivity()


设置
mResumedActivity
(最近启动的
Activity
) 为当前
ActivityRecord


调用
ActivityManagerService.addRecentTaskLocked()
将该
ActivityRecord.task
加入到最近任务列表;

调用
completeResumeLocked()
,发送消息处理上面的
Idler
对象,进而执行
ActivityManagerService.activityIdle()
:

释放
WakeLock
类型的
mLaunchingActivity
,它能防止启动
Activity
过程中掉电;

调用
processStoppingActivitiesLocked()
得到因本次启动而被 pause 的
Activity


如果他们处于 finishing 状态,则调用其
onDestroy()


否则调用其
onStop()


如果当前处于启动过程中(启动 Home 页面时),发送
ACTION_BOOT_COMPLETED
广播;

调用
checkReadyForSleepLocked()
检查调用过程中是否有休眠请求(比如用户按了电源键);

调用
ActivityManagerService.startSetupActivityLocked()
启动系统设置向导页面(初次使用时);

ActivityStack::startPausingLocked():

处理页面跳转前,
ActivityManagerService
会首先调用本方法处理当前活动的页面;

保存当前显示的
Activity
,并设置其
state
ActivityState.PAUSING


调用当前
Activity
所在进程的
schedulePauseActivity()
,内部调用
handlePauseActivity()
:

调用
Activity
onUserLeaving()

onPause()


设置
Activity
state
ActivityState.PAUSED


将暂停的
Activity
加入到
mStoppingActivities
中;

mStoppingActivities
数目大于 3,调用
scheduleIdleLocked()
,进而执行
ActivityManagerService.activityIdle()


调用
resumeTopActivityLocked()
启动目标
Activity


调用
WakeLock
类型变量
mLaunchingActivity.acquire()


调用当前
Activity
pauseKeyDispatchingLocked()
停止事件分发;

BroadcastReceiver 与 PendingResult 和 IIntentReceiver:

PendingResult
是 Android 2.3 新增的
BroadcastReceiver
内部类,用于异步处理广播消息:

先调用
BroadcastReceiver.goAsync()
得到一个
PendingResult
对象;

PendingResult
对象放到工作线程处理,使得
onReceive()
不会阻塞;

工作线程执行完后,需要调用
PendingResult.finish()
来完成整个广播的处理流程;

IIntentReceiver
用于广播相关的跨进程 Binder 通信;

ContextImpl::registerReceiverInternal():

如果没有传入
Handler
参数,调用
mMainThread.getHandler()
获取主线程
Handler


如果传入的
mPackageInfo
参数非空,调用
mPackageInfo.getReceiverDispatcher()
得到
IIntentReceiver
对象;

否则创建一个
LoadedApk.ReceiverDispatcher
对象;

调用
ActivityManagerService.registerReceiver()
方法:

调用
getRecordForAppLocked()

2 .检查
callerPackage
是否在
callearApp.pkgList
中,否则抛出
SecurityException


查询符合
IntentFilter
条件的 Sticky
Intent
,并返回第一个;

通过
mRegisteredReceivers
IIntentReceiver
得到
ReceiverList
对象:

一个
BroadcastReceiver
可设置多个过滤条件,也可以多次调用
registerReceiver()
使用不同条件,所以采用
ReceiverList
保存这种一对多关系;它继承自
ArrayList<BroadcastFilter>


ReceiverList
receiver
成员指向
IIntnetReceiver
对象;

ActivityManagerService
mRegisteredReceivers
保存所有
IIntentReceiver
和它对应的
ReceiverList


如果是首次调用,上面返回的
ReceiverList
对象为空,则创建该类型对象;

调用
IIntentReceiver.asBinder().linkToDeath()
监听广播接收者所在进程的死亡事件;

将上面的
ReceiverList
对象保存到
mRegisteredReceivers
中;

创建
IntentFilter
的子类
BroadcastFilter
对象,并调用
mReceiverResolver.addFilter()


ContextImpl::sendBroadcast():

内部调用
ActivityManagerService.broadcastIntentLocked()
:

如果是 Sticky 广播:

检查发送进程是否有
BROADCAST_STICKY
权限;

发送 Sticky 广播不能携带权限信息,也不能指定特定的接收对象;

将该
Intent
保存到
mStickyBrodcasts
中,如果存在则替换;

定义变量
receivers
(用于保存所有广播接收者)和
registeredReceivers
(用于保存动态注册的接收者);

如果通过
Intent
Component
指定了接收者,则从
PackageManagerService
查询接收者其信息;

通过
PackageManagerService
查询 Manifest 文件中声明的(静态)接收者,保存到
receivers


通过
ActivityManagerService
mReceiverResolver
对象查询所有动态注册的接收者,保存到
registeredReceivers


处理动态注册的接收者:

如果不是 Ordered 广播,直接创建
BroadcastRecord


如果没有被替换,保存到
mParcelledBroadcasts


调用
ActivityManagerService.scheduleBroadcastsLocked()
发送广播;

将动态注册者
registeredReceivers
的成员合并到
receivers
中;

创建
BroadcastRecord
对象,如果没有替换,保存到
mOrderedBroadcasts
(不区分是否 Ordered )中,并调用
ActivityManagerService.scheduleBroadcastsLocked()
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: