《深入理解 Android》笔记:ActivityManagerService
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
条件的 StickyIntent
,并返回第一个; -
通过
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()
;