深入理解 Android:ActivityManagerService
Linux 设置进程优先级函数:
int setpriority(int which, int who, int prio);
参数
which和who联合使用:which为PRIO_PROGRESS时,who代表进程;which为PRIO_PGROUP时,who代表进程组;which为PRIO_USER时,who代表uid;
参数
prio为优先级,范围 [-20,19],值越大,被调用几率越小;
Linux 设置进程调度策略函数:
int sched_setscheduler(pid_t pid, int policy, const struct sched_param *param);
参数
pid为进程 id;参数
policy为调度策略,目前 Android 只支持前三种(非实时调度策略):SCHED_OTHER: 默认值,标准的分时共享策略;SCHED_BATCH: 针对批处理进程的调度策略;SCHED_IDLE: 针对优先级非常低的适合在后台运行的策略;SCHED_FIFO: 队列调度策略;SCHED_RR: round-robin 循环调度策略;
由于 Android 不支持实时调度策略,参数
param必须为NULL;
oom_adj 与 lowmemorykiller:
Linux kernel 2.6.11 开始提供进程 OOM 控制机制:系统内存不足时,根据进程的
oom_adj值选择杀死某些进程以回收资源;oom_adj取值范围 [-16,15],值越大该进程越容易被系统杀掉;Linux 目前未提供设置进程
oom_adj的函数,只能通过修改/proc/进程id/oom_adj文件中的值来实现;Android 为 Linux kernel 新增的 lowmemorykiller 用于执行清理:
/sys/module/lowmemorykiller/parameters/minfree文件描述不同级别内存阈值(单位 KB);/sys/module/lowmemorykiller/parameters/adj文件描述不同内存阈值对应的oom_adj值;若 minfree 文件内容为
1024, 2048, 3072, 4096, 5120, 6144, adj 文件内容为0, 1, 2, 3, 4, 5,则表示剩余内存低于 1024 KB 时清理oom_adj大于 0 的进程;Android 4.0 之前 lowmemorykiller 的参数配置在 init.rc 中由 init 进程设置(未考虑屏幕尺寸影响);现在则由
ProcessList类综合考虑手机内存和屏幕尺寸后进行设置(该类还定义了各种进程的oom_adj值);
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:1表示需要等待调试器,否则直接启动;always_finish_activities: 当一个Activity不再有地方使用时是否立即执行 destroy;font_scale: 控制字体放大倍数(Android 4.0 新增);
调用传入的
Runnable类型的goingCallback参数的run():调用
startSystemUi(),启动SystemUIService(实现了系统状态栏);调用 Battery、Network 等其他模块的
systemReady(),启动Watchdog;
启动
persistent为1的 APK 进程(排除掉包名为android的 framework-res.apk,因为它之前已经被启动);调用
startHomeActivityLocked()启动 Home 界面;调用
finishBooting():注册 PACKAGE_RESTART 的
BroadcastReceiver处理包重启;启动那些等待启动的进程;
每隔 15 分钟检查一次各应用进程用电情况,杀掉使用
Wakelock时间过长的进程;调用
SytemProperties.set()设置sys.boot_completed属性为1;发送
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是否为0,检查权限信息;为
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;如果没有被替换,保存到
mParallelBroadcasts;调用
ActivityManagerService.scheduleBroadcastsLocked()发送广播;
将动态注册者
registeredReceivers的成员合并到receivers中;创建
BroadcastRecord对象,如果没有替换,保存到mOrderedBroadcasts(不区分是否 Ordered )中,并调用ActivityManagerService.scheduleBroadcastsLocked();
ActivityManagerService::processNextBroadcast():
调用
updateCpuStats()更新 CPU 信息;处理
mParallelBroadcasts中的所有BroadcastRecord:对于
BroadcastRecord的每个IIntentReceiver,调用deliverToRegisteredReceiverLocked():检查发送进程是否有
BroadcastFilter要求的权限;检查接收者是否有发送者要求的权限;
如果接收者所在进程不为空,则调用
ActivityThread.scheduleRegisteredReceiver();否则调用
IIntentReceiver.performReceive();
调用
addBroadcastToHistoryLocked()将处理过的BroadcastRecord加入mHistoryBrodcast供调试使用;
处理
mOrderedBroadcasts中的所有BroadcastRecord:如果处于 pending 状态的广播所在进程 pid 不为空(还未处理完),则继续等待;
调用
updateOomAdjLocked()更新 oom_adj;判断处理广播是否超时,如果超时则调用
broadcastTimeoutLocked();将该广播的处理结果传给设置了
resultTo的接收者;调用
cancelBroadcastTimeoutLocked()取消超时处理;调用
addBroadcastToHistoryLocked()保存广播记录;从
mOrderedBroadcasts中移除该广播;
记录本广播第一次处理的时间,并设置超时;
如果是动态接收者,直接调用前面的
deliverToRegisteredReceiverLocked()处理;检查权限;如果当前 app 所在进程 crash 了,重新调用一次
scheduleBroadcastsLocked();设置
BroadcastRecord的state、curComponent、curReceiver;调用
PackageManagerService.setPackageStoppedState()将 Package Stopped 状态设为fasle;如果接收者所在进程已经启动,调用应用进程的
scheduleReceiver();
ActivityThread::scheduleRegisteredReceiverLocked():
内部调用 LoadedApk.ReceiverDispatcher.performReceive():
创建
Args对象,它实现了Runnable接口;调用
mActivityThread.post(args),进而执行Args.run():获得
ClassLoader对象,并传递给Intent;调用接收者的
onReceive()方法;调用
ActivityManagerService.finishReceiver():调用
finishReceiverLocked()判断是否需要继续调度后续广播;如果需要继续调度,调用
processNextBroadcast();
如果
post()调用失败则调用Args.sendFinished(),传入参数为ActivityManagerService;
ActivityManagerService::updateLruProcessLocked():
获取该
ProcessRecord在mLruProcesses(其内部成员是按照lruWeight排序的) 中的索引lrui;如果大于 0,则从mLruProcesses中移除该进程;将
ProcessRecord.lastActivityTime设置为当前时间戳;设置
ProcessRecord.lruWeight:如果该进程包含
Activity,将lruWeight设置为lastActivityTime(即刚刚设置的时间戳)如果该进程包含
ContentProvider,将lruWeight设为lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET;否则将
lruWeight设为lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET;
从
mLruProcesses最后一个元素开始,通过比较lruWeight值,将当前ProcessRecord调整到合适的位置;如果没找到合适的位置,则将该
ProcessRecord添加为mLruProcesses第一个元素;如果
ProcessRecord.connections不为空(即绑定了Service),则调整所有绑定的Service所在进程的lruWeight;如果
ProcessRecord.conProviders不为空,也更新他们所在进程的lruWeight;
ActivityManagerService::updateOomAdjLocked():
调用
resumedActivityLock()获取当前处于前台的Activity,并得到对应的ProcessRecord对象;根据
ProcessList中定义的不可见进程的oom_adj值HIDDEN_APP_MAX_ADJ和HIDDEN_APP_MIN_ADJ确定等级数(numSlots);根据
mLruProcesses成员个数计算平均落在每个等级的进程数(factor值);从末尾遍历
mLruProcesses中的每个成员:调用
computeOomAdjLocked(),根据当前进程状态(是否前台、是否正在接收广播、是否正在运行服务等)以及ProcessList定义的 ADJ 阈值,更新进程的curRawAdj值;统计电量;
调用
Process.setOomAdj()更新该进程的oom_adj;如果
ProcessRecord的setSchedGroup和curSchedGroup不同,更新setSchedGroup为curSchedGroup;并且:如果
setSchedGroup值为THREAD_GROUP_BG_NONINTERACTIVE(后台非活动),调用Process.killProcessQuiet()杀掉该进程;否则,调用
Process.setProcessGroup()更新调度策略;
当某一个 adj 等级的进程处理数超过均值后,跳到下一等级处理;
如果后台进程数超过限制,调用
Process.killProcessQuiet()杀掉;
处理
ComponentCallback2相关逻辑:它是 Android 4.0 新增的接口,用于通知应用进程进行内存清理;
它内部定义了
onTrimMemory(int level)接口,四大组件除了BroadcastReceiver以外均实现了该接口;如果 hidden 状态的进程数超过了
ProcessList.MAX_HIDDEN_APPS值得一半,则调用ActivityThread.scheduleTrimMemory();
如果开启了
mAlwaysFinishActivities(始终销毁后台Activity, Android 4.0 新增特性),调用ActivityStack.destroyActivitiesLocked();
应用进程的 Crash 处理:
Zygote 在 fork 应用进程后会调用
Thread.setDefaultUncaughtExceptionHandler(new UncaughtHandler())处理未捕获异常;UncaughtHandler实现了Thread.UncaughtExceptionHandler接口,对未捕获异常的处理主要是uncaughtException()方法:调用
ActivityManagerService.handleApplicationCrash()处理应用 Crash:调用
findAppProcess()找到 Crash 进程的ProcessRecord;通知
DropBoxManagerService记录 Crash 日志;生成
app.crashReport,并从PakcageManagerService查询APP_ERROR的处理进程,如果返回false则处理结束;给
mHandler发送SHOW_ERROR_MSG消息,默认处理是弹框提示;启动一个
action是APP_ERROR的Activity处理错误报告;
调用
Process.killProcess()和System.exit()想方设法让进程结束 Java 世界;
Crash 进程退出后,
ActivityManagerService还会调用appDiedLocked()处理为它设置的AppDeathRecipient:如果该进程有打开的对话框(crash、anr、wait 等),关闭它们;
调用
killServicesLocked()处理该进程中驻留的Service或与其他进程Service建立的 Connection;如果有客户端在等待该进程中的
ContentProvider,则尝试重启该进程;否则调用removeDyingProvidersLocked();调用
removeReceiverLocked()移除该进程中的BroadcastReceiver;如果需要重启进程,则调用
startProcessLocked();从
mLruProcesses中移除该进程对应的ProcessRecord;遍历
mLruProcesses,找出 oom_adj 不小于ProcessList.HIDDEN_APP_MIN_ADJ的进程,并加入mProcessesToGc;发送
GC_BACKGROUND_PROCESSES_MSG给mHandler,进而调用应用进程的scheduleLowMemory()和processInBackground();
参考: