《深入理解 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();
1357

被折叠的 条评论
为什么被折叠?



