ActivityManagerService简称AMS,它是Android最核心的系统服务之一,AMS 是引导服务,AMS是Android进程管理和调度中心,负责应用进程的启动、切换和调度,以及四大组件的启动和管理,组件的状态管理和查询。可参考四大组件工作过程。AMS逻辑复杂,有一些类帮助它完成相关逻辑,它们统称为AMS家族。
AMS启动过程
在SystemServer 进程启动过程中,我们通过分析发现AMS是被SystemServer进程启动的。
public final class SystemServer implements Dumpable {
private SystemServiceManager mSystemServiceManager;
public static void main(String[] args) {
new SystemServer().run();
}
private void run() {
...
try {
t.traceBegin("StartServices");
//启动引导服务
startBootstrapServices(t);
//启动核心服务
startCoreServices(t);
//启动其它服务
startOtherServices(t);
//启动Apex服务
startApexServices(t);
} catch (Throwable ex) {
Slog.e("System", "******************************************");
Slog.e("System", "************ Failure starting system services", ex);
throw ex;
} finally {
t.traceEnd(); // StartServices
}
}
private void startBootstrapServices(@NonNull TimingsTraceAndSlog t) {
// Activity manager runs the show.
t.traceBegin("StartActivityManager");
// TODO: Might need to move after migration to WM.
ActivityTaskManagerService atm = mSystemServiceManager.startService(
ActivityTaskManagerService.Lifecycle.class).getService();
mActivityManagerService = ActivityManagerService.Lifecycle.startService(
mSystemServiceManager, atm);
mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
mActivityManagerService.setInstaller(installer);
mWindowManagerGlobalLock = atm.getGlobalLock();
t.traceEnd();
}
}
ActivityTaskManagerService
ActivityTaskManagerService是用于管理Activity及其容器(任务、显示等)的系统服务。
SystemServiceManager的startService
方法会调用Lifecycle的onStart
方法来启动ActivityTaskManagerService.
//frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
final ActivityTaskManagerInternal mInternal;
public static final class Lifecycle extends SystemService {
private final ActivityTaskManagerService mService;
public Lifecycle(Context context) {
super(context);
mService = new ActivityTaskManagerService(context);
}
@Override
public void onStart() {
publishBinderService(Context.ACTIVITY_TASK_SERVICE, mService);
mService.start();
}
public ActivityTaskManagerService getService() {
return mService;
}
}
private void start() {
LocalServices.addService(ActivityTaskManagerInternal.class, mInternal);
}
}
ActivityManagerService
调用静态内部类LifeCycle的startService
方法,接着调用SystemServiceManager类的startService
方法
public static final class Lifecycle extends SystemService {
private final ActivityManagerService mService;
private static ActivityTaskManagerService sAtm;
public Lifecycle(Context context) {
super(context);
mService = new ActivityManagerService(context, sAtm);
}
public static ActivityManagerService startService(
SystemServiceManager ssm, ActivityTaskManagerService atm) {
sAtm = atm;
return ssm.startService(ActivityManagerService.Lifecycle.class).getService();
}
@Override
public void onStart() {
mService.start();
}
@Override
public void onBootPhase(int phase) {
mService.mBootPhase = phase;
if (phase == PHASE_SYSTEM_SERVICES_READY) {
mService.mBatteryStatsService.systemServicesReady();
mService.mServices.systemServicesReady();
} else if (phase == PHASE_ACTIVITY_MANAGER_READY) {
mService.startBroadcastObservers();
} else if (phase == PHASE_THIRD_PARTY_APPS_CAN_START) {
mService.mPackageWatchdog.onPackagesReady();
}
}
@Override
public void onUserStopped(@NonNull TargetUser user) {
mService.mBatteryStatsService.onCleanupUser(user.getUserIdentifier());
}
public ActivityManagerService getService() {
return mService;
}
}
private void start() {
mBatteryStatsService.publish();
mAppOpsService.publish();
mProcessStats.publish();
Slog.d("AppOps", "AppOpsService published");
LocalServices.addService(ActivityManagerInternal.class, mInternal);
LocalManagerRegistry.addManager(ActivityManagerLocal.class,
(ActivityManagerLocal) mInternal);
mActivityTaskManager.onActivityManagerInternalAdded();
mPendingIntentController.onActivityManagerInternalAdded();
mAppProfiler.onActivityManagerInternalAdded();
CriticalEventLog.init();
}
startService
方法中创建AMS,mServices中添加AMS,最后又回到ActivityManagerService启动AMS。
//frameworks/base/services/core/java/com/android/server/SystemServiceManager.java
public <T extends SystemService> T startService(Class<T> serviceClass) {
try {
final String name = serviceClass.getName();
Slog.i(TAG, "Starting " + name);
Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StartService " + name);
// Create the service.
if (!SystemService.class.isAssignableFrom(serviceClass)) {
throw new RuntimeException("Failed to create " + name
+ ": service must extend " + SystemService.class.getName());
}
final T service;
try {
Constructor<T> constructor = serviceClass.getConstructor(Context.class);
service = constructor.newInstance(mContext);
} catch (InstantiationException ex) {
throw new RuntimeException("Failed to create service " + name
+ ": service could not be instantiated", ex);
} catch (IllegalAccessException ex) {
throw new RuntimeException("Failed to create service " + name
+ ": service must have a public constructor with a Context argument", ex);
} catch (NoSuchMethodException ex) {
throw new RuntimeException("Failed to create service " + name
+ ": service must have a public constructor with a Context argument", ex);
} catch (InvocationTargetException ex) {
throw new RuntimeException("Failed to create service " + name
+ ": service constructor threw an exception", ex);
}
startService(service);
return service;
} finally {
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
}
}
public void startService(@NonNull final SystemService service) {
// Check if already started
String className = service.getClass().getName();
if (mServiceClassnames.contains(className)) {
Slog.i(TAG, "Not starting an already started service " + className);
return;
}
mServiceClassnames.add(className);
// Register it.
mServices.add(service);
// Start it.
long time = SystemClock.elapsedRealtime();
try {
service.onStart();
} catch (RuntimeException ex) {
throw new RuntimeException("Failed to start service " + service.getClass().getName()
+ ": onStart threw an exception", ex);
}
warnIfTooLong(SystemClock.elapsedRealtime() - time, service, "onStart");
}
数据结构
ActivityRecord
它内部记录了Activity的所有信息,被用来描述一个Activity,它是在启动Activity时被创建的,具体是在ActivityStarter的executeRequest
方法中创建的。ActivityStartController是ActivityStarter的控制类,在activity启动过程文章中也提到了这部分,入口是ActivityTaskManagerService的startActivityAsUser
方法。
//frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
private int executeRequest(Request request) {
final ActivityRecord r = new ActivityRecord.Builder(mService)
.setCaller(callerApp)
.setLaunchedFromPid(callingPid)
.setLaunchedFromUid(callingUid)
.setLaunchedFromPackage(callingPackage)
.setLaunchedFromFeature(callingFeatureId)
.setIntent(intent)
.setResolvedType(resolvedType)
.setActivityInfo(aInfo)
.setConfiguration(mService.getGlobalConfiguration())
.setResultTo(resultRecord)
.setResultWho(resultWho)
.setRequestCode(requestCode)
.setComponentSpecified(request.componentSpecified)
.setRootVoiceInteraction(voiceSession != null)
.setActivityOptions(checkedOptions)
.setSourceRecord(sourceRecord)
.build();
}
//frameworks/base/services/core/java/com/android/server/wm/ActivityStartController.java
ActivityStartController(ActivityTaskManagerService service) {
this(service, service.mTaskSupervisor,
//工厂模式
new DefaultFactory(service, service.mTaskSupervisor,
new ActivityStartInterceptor(service, service.mTaskSupervisor)));
}
@VisibleForTesting
ActivityStartController(ActivityTaskManagerService service, ActivityTaskSupervisor supervisor,
Factory factory) {
mService = service;
mSupervisor = supervisor;
mFactory = factory;
mFactory.setController(this);
mPendingRemoteAnimationRegistry = new PendingRemoteAnimationRegistry(service.mGlobalLock,
service.mH);
mBalController = new BackgroundActivityStartController(mService, mSupervisor);
}
/**
* @return A starter to configure and execute starting an activity. It is valid until after
* {@link ActivityStarter#execute} is invoked. At that point, the starter should be
* considered invalid and no longer modified or used.
*/
ActivityStarter obtainStarter(Intent intent, String reason) {
return mFactory.obtain().setIntent(intent).setReason(reason);
}
从参数可以可以看出,内部存储了ATMS的引用,AndroidManifest的节点信息、Activity资源信息和进程相关信息等。
final class ActivityRecord extends WindowToken implements WindowManagerService.AppFreezeListener {
//构造者模式
static class Builder {
private final ActivityTaskManagerService mAtmService;
private WindowProcessController mCallerApp;
private int mLaunchedFromPid;
private int mLaunchedFromUid;
private String mLaunchedFromPackage;
private String mLaunchedFromFeature;
private Intent mIntent;
private String mResolvedType;
//代码中和AndroidManifest设置的节点信息
private ActivityInfo mActivityInfo;
private Configuration mConfiguration;
private ActivityRecord mResultTo;
private String mResultWho;
private int mRequestCode;
private boolean mComponentSpecified;
private boolean mRootVoiceInteraction;
private ActivityOptions mOptions;
private ActivityRecord mSourceRecord;
private PersistableBundle mPersistentState;
private TaskDescription mTaskDescription;
private long mCreateTime;
ActivityRecord build() {
if (mConfiguration == null) {
mConfiguration = mAtmService.getConfiguration();
}
return new ActivityRecord(mAtmService, mCallerApp, mLaunchedFromPid,
mLaunchedFromUid, mLaunchedFromPackage, mLaunchedFromFeature, mIntent,
mResolvedType, mActivityInfo, mConfiguration, mResultTo, mResultWho,
mRequestCode, mComponentSpecified, mRootVoiceInteraction,
mAtmService.mTaskSupervisor, mOptions, mSourceRecord, mPersistentState,
mTaskDescription, mCreateTime);
}
}
}
TaskRecord
它用来描述一个Activity任务栈,
ActivityStack
ActivityStack是一个管理类,用来管理所有Activity,其内部维护了Activity的所有状态、特殊状态的Activity以及Activity相关的列表等数据。ActivityStack是由ActivityStackSupervisor来进行管理,
Task
Task中可以包含多个ActivityRecord,并且调整ActivityRecord的显示位置。
Task 是一个 TaskFragment,可以包含一组执行特定任务的Activity。具有相同任务亲和力的Activity通常分组在同一个 Task 中。Task 也可以是显示在“最近”屏幕中与用户交互的任务的实体。Task 还可以包含其他 Task。
//frameworks/base/services/core/java/com/android/server/wm/Task.java
/**
* {@link Task} is a TaskFragment that can contain a group of activities to perform a certain job.
* Activities of the same task affinities usually group in the same {@link Task}. A {@link Task}
* can also be an entity that showing in the Recents Screen for a job that user interacted with.
* A {@link Task} can also contain other {@link Task}s.
*/
class Task extends TaskFragment {
}
TaskFragment
一个基本容器,可用于包含Activity或其他 TaskFragment,它还能够管理Activity生命周期并更新其中Activity的可见性。
//frameworks/base/services/core/java/com/android/server/wm/TaskFragment.java
/**
* A basic container that can be used to contain activities or other {@link TaskFragment}, which
* also able to manage the activity lifecycle and updates the visibilities of the activities in it.
*/
class TaskFragment extends WindowContainer<WindowContainer> {
}
TaskDisplayArea
TaskDisplayArea对应一个DisplayContent,负责管理屏幕里面的各种Task栈,包括调整各个Task的显示的位置。
DisplayArea 表示包含应用窗口容器的屏幕部分。子项可以是 Task 或 TaskDisplayArea。
//frameworks/base/services/core/java/com/android/server/wm/TaskDisplayArea.java
/**
* {@link DisplayArea} that represents a section of a screen that contains app window containers.
*
* The children can be either {@link Task} or {@link TaskDisplayArea}.
*/
final class TaskDisplayArea extends DisplayArea<WindowContainer> {
DisplayContent mDisplayContent; //对应屏幕
privates Task mRootHomeTak;//Home栈
private Task mRootPinnedTask;//画中画栈
Task mLastFocusedRootTask;//最近获得焦点的RootTask
private RootWindowContainer mRootWindowContainer;//屏幕管理
}
DisplayContent
DisplayContent 代表的是一块屏幕,其被RootWindowContainer所管理,该显示屏上的窗口以栈的形式管理,DisplayContent有四种形式的container,分别用来存储不同类型的窗口:应用程序窗口,系统类型窗口,输入法窗口和壁纸窗口,在addWindowToken中决定添加到那个Container中。
//frameworks/base/services/core/java/com/android/server/wm/DisplayContent.java
/**
* Utility class for keeping track of the WindowStates and other pertinent contents of a
* particular Display.
*/
class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.DisplayContentInfo {
final int mDisplayId;//屏幕ID
final Display mDisplay;//对应物理屏幕
private final DisplayInfo mDisplayInfo = new DisplayInfo();//屏幕信息
private final DisplayRotation mDisplayRotation;//屏幕转向控制
}
RootWindowContainer
它是窗口容器的根容器,子容器是DisplayContent。RootWindowContainer的初始化是在WindowManagerService中完成的。主要用来管理显示屏幕,其关联一组DisplayContent。
//frameworks/base/services/core/java/com/android/server/wm/RootWindowContainer.java
/** Root {@link WindowContainer} for the device. */
class RootWindowContainer extends WindowContainer<DisplayContent>
implements DisplayManager.DisplayListener {}
组件管理
Activity管理
Activity状态
//frameworks/base/services/core/java/com/android/server/wm/ActivityRecord.java
public final class ActivityRecord extends WindowToken implements WindowManagerService.AppFreezeListener {
enum State {
INITIALIZING,//正在初始化
STARTED,//启动状态
RESUMED,//恢复状态
PAUSING,//正在暂停
PAUSED,//暂停状态
STOPPING,//正在停止
STOPPED,//停止状态
FINISHING,//正在结束
DESTROYING,//正在销毁
DESTROYED,//销毁状态
RESTARTING_PROCESS//正在重启
}
}
Activity类型
//frameworks/base/core/java/android/app/WindowConfiguration.java
public class WindowConfiguration implements Parcelable, Comparable<WindowConfiguration> {
private @ActivityType int mActivityType;
/** Activity type is currently not defined. */
public static final int ACTIVITY_TYPE_UNDEFINED = 0;
/** Standard activity type. Nothing special about the activity... */
public static final int ACTIVITY_TYPE_STANDARD = 1;
/** Home/Launcher activity type. */
public static final int ACTIVITY_TYPE_HOME = 2;
/** Recents/Overview activity type. There is only one activity with this type in the system. */
public static final int ACTIVITY_TYPE_RECENTS = 3;
/** Assistant activity type. */
public static final int ACTIVITY_TYPE_ASSISTANT = 4;
/** Dream activity type. */
public static final int ACTIVITY_TYPE_DREAM = 5;
/** @hide */
@IntDef(prefix = { "ACTIVITY_TYPE_" }, value = {
ACTIVITY_TYPE_UNDEFINED,//未定义类型
ACTIVITY_TYPE_STANDARD,//标准类型
ACTIVITY_TYPE_HOME,//Home类型
ACTIVITY_TYPE_RECENTS,//最近认为类型
ACTIVITY_TYPE_ASSISTANT,//助手类型
ACTIVITY_TYPE_DREAM,//VR类型
})
public @interface ActivityType {}
}
AMS可能管理多个屏幕设备,由RootWindowContainer管理。每个屏幕在AMS中对应一个DisplayContent的数据结构。一个屏幕由一个TaskDisplayArea管理里面的Task,一个Task里可能会有多个ActivityRecord。
Service管理
Service工作流程文章之前有提到过,ServiceRecord记录了AMS中某一个运行的Service的信息,是AMS管理Service的基本单位,一个Service可以被其它进程用不同的Intent来绑定,使用同一个Intent绑定的Service可能是不同的进程,所以会有多个Connection连接。
//frameworks/base/services/core/java/com/android/server/am/ServiceRecord.java
final class ServiceRecord extends Binder implements ComponentName.WithComponentName {
final ServiceInfo serviceInfo; //manifest中Service的信息
boolean isForeground;//当前service是否是一个前台进程
boolean startRequested;//service是否由startService启动
}
ActiveServices是AMS中负责管理Service的类,mServiceMap是ServiceMap类型,ServiceMap中保存了运行的Service信息ServiceRecord,有两种保存形式,一种是CompomentName,一种是Intent。
public final class ActiveServices {
final SparseArray<ServiceMap> mServiceMap = new SparseArray<>();
}
Broadcast管理
在AMS中,BroadcastReceiver的过滤条件由BroadcastFilter表示,该类从IntentFilter派生,由于一个BroadcastReceiver可以设置多个过滤条件,因此AMS使用ReceiverList来表达一对多的关系。
AMS提供mRegisteredReceivers用于保存IIntentReceiver和对应ReceiverList的关系。mReceiverResolver存储所有动态注册的BroadcastReceiver设置的过滤条件。
//frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
public class ActivityManagerService extends IActivityManager.Stub
implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback, ActivityManagerGlobalLock {
final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
= new IntentResolver<BroadcastFilter, BroadcastFilter>() {
@Override
protected boolean allowFilterResult(
BroadcastFilter filter, List<BroadcastFilter> dest) {
IBinder target = filter.receiverList.receiver.asBinder();
for (int i = dest.size() - 1; i >= 0; i--) {
if (dest.get(i).receiverList.receiver.asBinder() == target) {
return false;
}
}
return true;
}
@Override
protected BroadcastFilter newResult(@NonNull Computer computer, BroadcastFilter filter,
int match, int userId, long customFlags) {
if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
|| userId == filter.owningUserId) {
return super.newResult(computer, filter, match, userId, customFlags);
}
return null;
}
@Override
protected IntentFilter getIntentFilter(@NonNull BroadcastFilter input) {
return input;
}
@Override
protected BroadcastFilter[] newArray(int size) {
return new BroadcastFilter[size];
}
@Override
protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
return packageName.equals(filter.packageName);
}
};
}
进程管理
进程分类
Android系统中,进程主要分为以下几类:
-
前台进程(Foreground process)
- 页面正在显示的Activity
- 包含一个Service,并且该Service和一个显示的Activity绑定
- 包含调用了startForeground的Service,或该进程Service正在调用其生命周期方法
- 该进程有BroadcastReceiver的实例正在执行onReceive方法
-
可见进程(Visible process)
进程拥有一个可见的但非前台的Activity(例如Activity处于onPause状态,但是仍然对用户可见,如弹出对话框)。
当系统内存不足,且需要回收资源以供前台进程使用时,可能会杀死这些进程。
-
服务进程(Service process)
进程中运行着已使用startService()方法启动的服务。
尽管这些进程对用户不是直接可见的,但它们通常在执行一些用户关心的操作(如后台播放音乐或下载数据)。
-
后台进程(Background process)
进程包含不可见的Activity(已调用onStop())。
系统可能随时终止这些进程以回收内存,并且当内存充足时,通常保留它们的进程状态和内存数据,以便用户返回时能够快速恢复
-
空进程(Empty process)
这类进程不包含任何活跃的应用组件。
系统保留这类进程的目的是为了缓存,以便下次可以更快地启动应用。
系统经常终止这些进程以保持系统的整体性能。Android系统会根据进程中运行的组件及其状态来调整进程的优先级,当系统内存不足时,会按照上述分类从低优先级到高优先级依次清理进程。
管理
AMS是管理进程的核心模块,在AMS中,每个进程以一个记录的形式存在,即ProcessRecord
四大组件定义在AndroidManifest文件中,每一个都可以使用android:process=""
来指定进程,同一个APP可以运行在多个进程,多个APP也可以共享一个进程。android:priority=""
设置进程优先级,数值越大,进程优先级越高。
进程的创建在Activity启动过程中已经说明过,Zygote进程会fork应用进程。至于进程的退出,AMS会完成进程退出的善后工作,清理进程和进程组。
class ProcessRecord implements WindowProcessListener {
//退出进程
void killLocked(String reason, String description, @Reason int reasonCode,
@SubReason int subReason, boolean noisy, boolean asyncKPG) {
if (!mKilledByAm) {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "kill");
if (reasonCode == ApplicationExitInfo.REASON_ANR
&& mErrorState.getAnrAnnotation() != null) {
description = description + ": " + mErrorState.getAnrAnnotation();
}
if (mService != null && (noisy || info.uid == mService.mCurOomAdjUid)) {
mService.reportUidInfoMessageLocked(TAG,
"Killing " + toShortString() + " (adj " + mState.getSetAdj()
+ "): " + reason, info.uid);
}
// Since the process is getting killed, reset the freezable related state.
mOptRecord.setPendingFreeze(false);
mOptRecord.setFrozen(false);
if (mPid > 0) {
mService.mProcessList.noteAppKill(this, reasonCode, subReason, description);
EventLog.writeEvent(EventLogTags.AM_KILL,
userId, mPid, processName, mState.getSetAdj(), reason, getRss(mPid));
Process.killProcessQuiet(mPid);
killProcessGroupIfNecessaryLocked(asyncKPG);
} else {
mPendingStart = false;
}
if (!mPersistent) {
synchronized (mProcLock) {
mKilled = true;
mKilledByAm = true;
mKillTime = SystemClock.uptimeMillis();
}
}
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
}
}
}
内存管理
Android操作系统的内存回收分为两部分,默认内存回收和内核级内存回收,在Activity生命周期切换时,会触发AMS的回收机制。
AMS中内存回收触发的几种场景如下:
- 调用
startActivity
,一般情况下,页面跳转时,会暂停当前Activity,在Activity启动过程中,我们知道会调用resumeTopActivity
方法,期间会调用ActivityRecord的addToStopping
释放资源。
//frameworks/base/services/core/java/com/android/server/wm/TaskFragment.java
class TaskFragment extends WindowContainer<WindowContainer> {
final boolean resumeTopActivity(ActivityRecord prev, ActivityOptions options,
boolean skipPause) {
...
boolean pausing = !skipPause && taskDisplayArea.pauseBackTasks(next);
if (mResumedActivity != null) {
ProtoLog.d(WM_DEBUG_STATES, "resumeTopActivity: Pausing %s", mResumedActivity);
pausing |= startPausing(mTaskSupervisor.mUserLeaving, false /* uiSleeping */,
next, "resumeTopActivity");
}
}
boolean startPausing(boolean userLeaving, boolean uiSleeping, ActivityRecord resuming,
String reason) {
if (mPausingActivity != null) {
Slog.wtf(TAG, "Going to pause when pause is already pending for " + mPausingActivity
+ " state=" + mPausingActivity.getState());
if (!shouldSleepActivities()) {
// Avoid recursion among check for sleep and complete pause during sleeping.
// Because activity will be paused immediately after resume, just let pause
// be completed by the order of activity paused from clients.
completePause(false, resuming);
}
...
}
void completePause(boolean resumeNext, ActivityRecord resuming) {
ActivityRecord prev = mPausingActivity;
if (prev != null) {
prev.setWillCloseOrEnterPip(false);
final boolean wasStopping = prev.isState(STOPPING);
prev.setState(PAUSED, "completePausedLocked");
if (prev.finishing) {
ProtoLog.v(WM_DEBUG_STATES, "Executing finish of activity: %s", prev);
prev = prev.completeFinishing(false /* updateVisibility */,
"completePausedLocked");
} else if (prev.attachedToProcess()) {
ProtoLog.v(WM_DEBUG_STATES, "Enqueue pending stop if needed: %s "
+ "wasStopping=%b visibleRequested=%b", prev, wasStopping,
prev.isVisibleRequested());
if (wasStopping) {
prev.setState(STOPPING, "completePausedLocked");
} else if (!prev.isVisibleRequested() || shouldSleepOrShutDownActivities()) {
prev.setDeferHidingClient(false);
// If we were visible then resumeTopActivities will release resources before
// stopping.
prev.addToStopping(true /* scheduleIdle */, false /* idleDelayed */,
"completePauseLocked");
}
} else {
ProtoLog.v(WM_DEBUG_STATES, "App died during pause, not stopping: %s", prev);
prev = null;
}
}
}
mStoppingActivities是保存pause的Activity列表,同时判断mStoppingActivities的Activity数量是否超过3个,超过则会清除这些Activity。调用ActivityTaskSupervisor类的scheduleIdle
方法。
//frameworks/base/services/core/java/com/android/server/wm/ActivityRecord.java
final class ActivityRecord extends WindowToken implements WindowManagerService.AppFreezeListener {
final ActivityTaskSupervisor mTaskSupervisor;
private static final int MAX_STOPPING_TO_FORCE = 3;
void addToStopping(boolean scheduleIdle, boolean idleDelayed, String reason) {
void addToStopping(boolean scheduleIdle, boolean idleDelayed, String reason) {
if (!mTaskSupervisor.mStoppingActivities.contains(this)) {
EventLogTags.writeWmAddToStopping(mUserId, System.identityHashCode(this),
shortComponentName, reason);
mTaskSupervisor.mStoppingActivities.add(this);
}
final Task rootTask = getRootTask();
// If we already have a few activities waiting to stop, then give up on things going idle
// and start clearing them out. Or if r is the last of activity of the last task the root
// task will be empty and must be cleared immediately.
boolean forceIdle = mTaskSupervisor.mStoppingActivities.size() > MAX_STOPPING_TO_FORCE
|| (isRootOfTask() && rootTask.getChildCount() <= 1);
if (scheduleIdle || forceIdle) {
ProtoLog.v(WM_DEBUG_STATES,
"Scheduling idle now: forceIdle=%b immediate=%b", forceIdle, !idleDelayed);
if (!idleDelayed) {
mTaskSupervisor.scheduleIdle();
} else {
mTaskSupervisor.scheduleIdleTimeout(this);
}
} else {
rootTask.checkReadyForSleep();
}
}
}
ActivityTaskSupervisor类中发送IDLE_NOW_MSG
消息处理内存,最终调用activityIdleInternal
方法,第三种场景会继续分析。
//frameworks/base/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
//规定10s启动Activity,否则释放相关资源
private static final int IDLE_TIMEOUT = 10 * 1000 * Build.HW_TIMEOUT_MULTIPLIER;
void scheduleIdleTimeout(ActivityRecord next) {
if (DEBUG_IDLE) Slog.d(TAG_IDLE, "scheduleIdleTimeout: Callers=" + Debug.getCallers(4));
Message msg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG, next);
mHandler.sendMessageDelayed(msg, IDLE_TIMEOUT);
}
final void scheduleIdle() {
if (!mHandler.hasMessages(IDLE_NOW_MSG)) {
if (DEBUG_IDLE) Slog.d(TAG_IDLE, "scheduleIdle: Callers=" + Debug.getCallers(4));
mHandler.sendEmptyMessage(IDLE_NOW_MSG);
}
}
private boolean handleMessageInner(Message msg) {
switch (msg.what) {
case IDLE_TIMEOUT_MSG: {
if (DEBUG_IDLE) Slog.d(TAG_IDLE,
"handleMessage: IDLE_TIMEOUT_MSG: r=" + msg.obj);
// We don't at this point know if the activity is fullscreen, so we need to be
// conservative and assume it isn't.
activityIdleFromMessage((ActivityRecord) msg.obj, true /* fromTimeout */);
} break;
case IDLE_NOW_MSG: {
if (DEBUG_IDLE) Slog.d(TAG_IDLE, "handleMessage: IDLE_NOW_MSG: r=" + msg.obj);
activityIdleFromMessage((ActivityRecord) msg.obj, false /* fromTimeout */);
} break;
}
}
private void activityIdleFromMessage(ActivityRecord idleActivity, boolean fromTimeout) {
activityIdleInternal(idleActivity, fromTimeout,
fromTimeout /* processPausingActivities */, null /* config */);
}
}
- 用户按back按键,退出应用程序。
- 当Activity启动后,进入onResume生命周期时,会向AMS发送一个Idle信息,这会触发AMS执行ActivityClient类的
activityIdle
方法,源码如下:
//frameworks/base/core/java/android/app/ActivityThread.java
public final class ActivityThread extends ClientTransactionHandler
implements ActivityThreadInternal {
@Override
public void handleResumeActivity(ActivityClientRecord r, boolean finalStateRequest,
boolean isForward, boolean shouldSendCompatFakeFocus, String reason) {
...
if (localLOGV) Slog.v(TAG, "Scheduling idle handler for " + r);
Looper.myQueue().addIdleHandler(new Idler());
}
private class Idler implements MessageQueue.IdleHandler {
@Override
public final boolean queueIdle() {
boolean stopProfiling = false;
if (mBoundApplication != null && mProfiler.profileFd != null
&& mProfiler.autoStopProfiler) {
stopProfiling = true;
}
final ActivityClient ac = ActivityClient.getInstance();
while (mNewActivities.size() > 0) {
final ActivityClientRecord a = mNewActivities.remove(0);
if (localLOGV) {
Slog.v(TAG, "Reporting idle of " + a + " finished="
+ (a.activity != null && a.activity.mFinished));
}
if (a.activity != null && !a.activity.mFinished) {
ac.activityIdle(a.token, a.createdConfig, stopProfiling);
a.createdConfig = null;
}
}
if (stopProfiling) {
mProfiler.stopProfiling();
}
return false;
}
}
//frameworks/base/core/java/android/app/ActivityClient.java
public class ActivityClient {
public void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
try {
getActivityClientController().activityIdle(token, config, stopProfiling);
} catch (RemoteException e) {
e.rethrowFromSystemServer();
}
}
private static IActivityClientController getActivityClientController() {
final IActivityClientController controller = INTERFACE_SINGLETON.mKnownInstance;
return controller != null ? controller : INTERFACE_SINGLETON.get();
}
}
它的实现在ActivityClientController中,最终还是调用ActivityTaskSupervisor类的activityIdleInternal
方法,和第一种场景一致。
//frameworks/base/services/core/java/com/android/server/wm/ActivityClientController.java
class ActivityClientController extends IActivityClientController.Stub {
private final ActivityTaskSupervisor mTaskSupervisor;
@Override
public void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
final long origId = Binder.clearCallingIdentity();
try {
synchronized (mGlobalLock) {
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "activityIdle");
final ActivityRecord r = ActivityRecord.forTokenLocked(token);
if (r == null) {
return;
}
mTaskSupervisor.activityIdleInternal(r, false /* fromTimeout */,
false /* processPausingActivities */, config);
if (stopProfiling && r.hasProcess()) {
r.app.clearProfilerIfNeeded();
}
}
} finally {
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
Binder.restoreCallingIdentity(origId);
}
}
首先调用ATMS的scheduleAppGcsLocked
方法通知所有需要回收内存的进程进行内存回收。processStoppingAndFinishingActivities
方法主要是取出mStoppingActivities的Activity,并存放到readyToStopActivities列表中,清空了mStoppingActivities列表,然后判断readyToStopActivities中是否在堆栈中,然后在判断是否销毁,是则执行destory方法,否则执行stop方法进行停止。最后ATMS的的handler发送了一条信息。
//frameworks/base/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
final ActivityTaskManagerService mService;
void activityIdleInternal(ActivityRecord r, boolean fromTimeout,
boolean processPausingActivities, Configuration config) {
...
if (mRootWindowContainer.allResumedActivitiesIdle()) {
if (r != null) {
mService.scheduleAppGcsLocked();
mRecentTasks.onActivityIdle(r);
}
...
}
// Atomically retrieve all of the other things to do.
processStoppingAndFinishingActivities(r, processPausingActivities, "idle");
...
mService.mH.post(() -> mService.mAmInternal.trimApplications());
}
void processStoppingAndFinishingActivities(ActivityRecord launchedActivity,
boolean processPausingActivities, String reason) {
for (int i = 0; i < mStoppingActivities.size(); i++) {
final ActivityRecord s = mStoppingActivities.get(i);
...
if (readyToStopActivities == null) {
readyToStopActivities = new ArrayList<>();
}
readyToStopActivities.add(s);
mStoppingActivities.remove(i);
i--;
}
...
final int numReadyStops = readyToStopActivities == null ? 0 : readyToStopActivities.size();
for (int i = 0; i < numReadyStops; i++) {
final ActivityRecord r = readyToStopActivities.get(i);
if (r.isInHistory()) {
if (r.finishing) {
// TODO(b/137329632): Wait for idle of the right activity, not just any.
r.destroyIfPossible(reason);
} else {
r.stopIfPossible();
}
}
}
}
}
ActivityManagerInternal是一个抽象类,它的实现在AMS中,trimApplicationsLocked
方法中主要删除mRemovedProcesses中的进程,主要包含以下几种场景:
- crash进程
- 5S没有响应并被用户选择关闭的进程
- 调用了killBackgroundProcesses想要杀死的进程
- 系统启动时,在AMS
SystemReady
方法中,非Persistent的应用进程
接着调用updateOomAdjLocked
方法更新进程的优先级并通知Linux内核(LowMemoryKiller),内核根据系统内存的使用情况以及adj的值动态管理进程资源,adj作为Linux内核的参考依据。进程的优先级即进程的oom_adj值,值越小优先级越高,最后被杀死。
public class ActivityManagerService extends IActivityManager.Stub
implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback, ActivityManagerGlobalLock {
OomAdjuster mOomAdjuster;
public final class LocalService extends ActivityManagerInternal
implements ActivityManagerLocal {
@Override
public void trimApplications() {
ActivityManagerService.this.trimApplications(true, OOM_ADJ_REASON_ACTIVITY);
}
}
private void trimApplications(boolean forceFullOomAdj, @OomAdjReason int oomAdjReason) {
synchronized (this) {
trimApplicationsLocked(forceFullOomAdj, oomAdjReason);
}
}
private void trimApplicationsLocked(boolean forceFullOomAdj, @OomAdjReason int oomAdjReason) {
for (int i = mProcessList.mRemovedProcesses.size() - 1; i >= 0; i--) {
final ProcessRecord app = mProcessList.mRemovedProcesses.get(i);
if (!app.hasActivitiesOrRecentTasks()
&& app.mReceivers.numberOfCurReceivers() == 0
&& app.mServices.numberOfRunningServices() == 0) {
final IApplicationThread thread = app.getThread();
Slog.i(TAG, "Exiting empty application process "
+ app.toShortString() + " ("
+ (thread != null ? thread.asBinder() : null)
+ ")\n");
final int pid = app.getPid();
if (pid > 0 && pid != MY_PID) {
app.killLocked("empty",
ApplicationExitInfo.REASON_OTHER,
ApplicationExitInfo.SUBREASON_TRIM_EMPTY,
false);
} else if (thread != null) {
try {
thread.scheduleExit();
} catch (Exception e) {
// Ignore exceptions.
}
}
didSomething = true;
cleanUpApplicationRecordLocked(app, pid, false, true, -1, false /*replacingPid*/,
false /* fromBinderDied */);
mProcessList.mRemovedProcesses.remove(i);
if (app.isPersistent()) {
addAppLocked(app.info, null, false, null /* ABI override */,
ZYGOTE_POLICY_FLAG_BATCH_LAUNCH);
app.mProfile.addHostingComponentType(HOSTING_COMPONENT_TYPE_PERSISTENT);
}
}
}
// Now update the oom adj for all processes. Don't skip this, since other callers
// might be depending on it.
if (didSomething || forceFullOomAdj) {
updateOomAdjLocked(oomAdjReason);
} else {
// Process any pending oomAdj targets, it'll be a no-op if nothing is pending.
updateOomAdjPendingTargetsLocked(oomAdjReason);
}
}
final void updateOomAdjLocked(@OomAdjReason int oomAdjReason) {
mOomAdjuster.updateOomAdjLocked(oomAdjReason);
}
}
OomAdjuster类的updateOomAdjLocked
方法中,最终调用到updateOomAdjInnerLSP
方法中,通过computeOomAdjLSP
方法计算进程的oom_adj值。assignCachedAdjIfNecessary
方法将未分配Adj值的进程根据进程状态分为后台缓存进程和empty进程.updateAndTrimProcessLSP
方法会遍历mLruProcesses列表,调用applyOomAdjLSP
方法,向/proc/进程号/oom_score_adj文件写入计算出来的oom_adj值,然后杀掉超过限制的后台缓存进程和empty进程,默认限制是后台缓存进程和empty进程各16个,isolated进程不包含服务直接回收,最后调用updateLowMemStateLSP
方法进行内存调整。
public class OomAdjuster {
void updateOomAdjLocked(@OomAdjReason int oomAdjReason) {
synchronized (mProcLock) {
updateOomAdjLSP(oomAdjReason);
}
}
private void updateOomAdjLSP(@OomAdjReason int oomAdjReason) {
if (checkAndEnqueueOomAdjTargetLocked(null)) {
// Simply return as there is an oomAdjUpdate ongoing
return;
}
try {
mOomAdjUpdateOngoing = true;
performUpdateOomAdjLSP(oomAdjReason);
} finally {
// Kick off the handling of any pending targets enqueued during the above update
mOomAdjUpdateOngoing = false;
updateOomAdjPendingTargetsLocked(oomAdjReason);
}
}
private void performUpdateOomAdjLSP(@OomAdjReason int oomAdjReason) {
final ProcessRecord topApp = mService.getTopApp();
// Clear any pending ones because we are doing a full update now.
mPendingProcessSet.clear();
mService.mAppProfiler.mHasPreviousProcess = mService.mAppProfiler.mHasHomeProcess = false;
updateOomAdjInnerLSP(oomAdjReason, topApp , null, null, true, true);
}
protected void updateOomAdjInnerLSP(@OomAdjReason int oomAdjReason, final ProcessRecord topApp,
ArrayList<ProcessRecord> processes, ActiveUids uids, boolean potentialCycles,
boolean startProfiling) {
ArrayList<ProcessRecord> lruList = mProcessList.getLruProcessesLOSP();
final int numLru = lruList.size();
for (int i = numProc - 1; i >= 0; i--) {
ProcessRecord app = activeProcesses.get(i);
final ProcessStateRecord state = app.mState;
if (!app.isKilledByAm() && app.getThread() != null) {
state.setProcStateChanged(false);
app.mOptRecord.setLastOomAdjChangeReason(oomAdjReason);
// It won't enter cycle if not computing clients.
computeOomAdjLSP(app, UNKNOWN_ADJ, topApp, fullUpdate, now, false,
computeClients, oomAdjReason, true);
// if any app encountered a cycle, we need to perform an additional loop later
retryCycles |= state.containsCycle();
// Keep the completedAdjSeq to up to date.
state.setCompletedAdjSeq(mAdjSeq);
}
}
...
assignCachedAdjIfNecessary(mProcessList.getLruProcessesLOSP());
postUpdateOomAdjInnerLSP(oomAdjReason, activeUids, now, nowElapsed, oldTime);
if (startProfiling) {
mService.mOomAdjProfiler.oomAdjEnded();
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
}
}
protected void postUpdateOomAdjInnerLSP(@OomAdjReason int oomAdjReason, ActiveUids activeUids,
long now, long nowElapsed, long oldTime) {
final boolean allChanged = updateAndTrimProcessLSP(now, nowElapsed, oldTime, activeUids,
oomAdjReason);
...
}
private boolean updateAndTrimProcessLSP(final long now, final long nowElapsed,
final long oldTime, final ActiveUids activeUids, @OomAdjReason int oomAdjReason) {
for (int i = numLru - 1; i >= 0; i--) {
if (!app.isKilledByAm() && app.getThread() != null) {
// We don't need to apply the update for the process which didn't get computed
if (state.getCompletedAdjSeq() == mAdjSeq) {
applyOomAdjLSP(app, true, now, nowElapsed, oomAdjReason);
}
final ProcessServiceRecord psr = app.mServices;
// Count the number of process types.
switch (state.getCurProcState()) {
case PROCESS_STATE_CACHED_ACTIVITY:
case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
mNumCachedHiddenProcs++;
numCached++;
final int connectionGroup = psr.getConnectionGroup();
if (connectionGroup != 0) {
if (lastCachedGroupUid == app.info.uid
&& lastCachedGroup == connectionGroup) {
numCachedExtraGroup++;
} else {
lastCachedGroupUid = app.info.uid;
lastCachedGroup = connectionGroup;
}
} else {
lastCachedGroupUid = lastCachedGroup = 0;
}
if ((numCached - numCachedExtraGroup) > cachedProcessLimit) {
app.killLocked("cached #" + numCached,
"too many cached",
ApplicationExitInfo.REASON_OTHER,
ApplicationExitInfo.SUBREASON_TOO_MANY_CACHED,
true);
} else if (proactiveKillsEnabled) {
lruCachedApp = app;
}
break;
case PROCESS_STATE_CACHED_EMPTY:
if (numEmpty > mConstants.CUR_TRIM_EMPTY_PROCESSES
&& app.getLastActivityTime() < oldTime) {
app.killLocked("empty for " + ((now
- app.getLastActivityTime()) / 1000) + "s",
"empty for too long",
ApplicationExitInfo.REASON_OTHER,
ApplicationExitInfo.SUBREASON_TRIM_EMPTY,
true);
} else {
numEmpty++;
if (numEmpty > emptyProcessLimit) {
app.killLocked("empty #" + numEmpty,
"too many empty",
ApplicationExitInfo.REASON_OTHER,
ApplicationExitInfo.SUBREASON_TOO_MANY_EMPTY,
true);
} else if (proactiveKillsEnabled) {
lruCachedApp = app;
}
}
break;
default:
mNumNonCachedProcs++;
break;
}
// TODO: b/319163103 - limit isolated/sandbox trimming to just the processes
// evaluated in the current update.
if (app.isolated && psr.numberOfRunningServices() <= 0
&& app.getIsolatedEntryPoint() == null) {
app.killLocked("isolated not needed", ApplicationExitInfo.REASON_OTHER,
ApplicationExitInfo.SUBREASON_ISOLATED_NOT_NEEDED, true);
} else if (app.isSdkSandbox && psr.numberOfRunningServices() <= 0
&& app.getActiveInstrumentation() == null) {
app.killLocked("sandbox not needed", ApplicationExitInfo.REASON_OTHER,
ApplicationExitInfo.SUBREASON_SDK_SANDBOX_NOT_NEEDED, true);
} else {
// Keeping this process, update its uid.
updateAppUidRecLSP(app);
}
if (state.getCurProcState() >= ActivityManager.PROCESS_STATE_HOME
&& !app.isKilledByAm()) {
numTrimming++;
}
}
}
if (proactiveKillsEnabled // Proactive kills enabled?
&& doKillExcessiveProcesses // Should kill excessive processes?
&& freeSwapPercent < lowSwapThresholdPercent // Swap below threshold?
&& lruCachedApp != null // If no cached app, let LMKD decide
// If swap is non-decreasing, give reclaim a chance to catch up
&& freeSwapPercent < mLastFreeSwapPercent) {
lruCachedApp.killLocked("swap low and too many cached",
ApplicationExitInfo.REASON_OTHER,
ApplicationExitInfo.SUBREASON_TOO_MANY_CACHED,
true);
}
mLastFreeSwapPercent = freeSwapPercent;
return mService.mAppProfiler.updateLowMemStateLSP(numCached, numEmpty, numTrimming, now);
}
}
}
OOM ADJ的定义在ProcessList类中。
//无法确定的adj,要缓存的进程或空进程
public static final int UNKNOWN_ADJ = 1001;
//不可见进程的Adj最大值
public static final int CACHED_APP_MAX_ADJ = 999;
//不可见进程的Adj最小值
public static final int CACHED_APP_MIN_ADJ = 900;
//允许终止的oom_adj值
public static final int CACHED_APP_LMK_FIRST_ADJ = 950;
//B List的Service,和A List相比,对用户的黏合度小些
public static final int SERVICE_B_ADJ = 800;
//用户前一次交互的进程
public static final int PREVIOUS_APP_ADJ = 700;
//Launcher进程Adj
public static final int HOME_APP_ADJ = 600;
//应用服务进程
public static final int SERVICE_ADJ = 500;
//后台的重量级进程
public static final int HEAVY_WEIGHT_APP_ADJ = 400;
//承载backup相关操作的进程
public static final int BACKUP_APP_ADJ = 300;
//低感知进程
public static final int PERCEPTIBLE_LOW_APP_ADJ = 250;
//可见APP adj
public static final int VISIBLE_APP_ADJ = 100;
//前台APP adj
public static final int FOREGROUND_APP_ADJ = 0;
//系统进程
public static final int SYSTEM_ADJ = -900;
//Native 进程,不被系统管理
public static final int NATIVE_ADJ = -1000;
.....
LowMemoryKiller是Android基于Linux的OOM Killer定制的进程管理功能,通过对进程的资源管理来保证Android系统可以流畅运行,避免内存不足造成系统异常。
AMS实时更新oom_adj的值,并将此值传递到Linux Kernel中,Kernel有低内存回收机制,在内存达到一定阈值后触发kill oom_adj高的进程。可以通过cat /proc/pid 号/oom_score_adj查看每个进程的oom_adj值。
总结
AMS担任的角色实在是太多了,一两篇文章不可能将它的所有"魅力"展示出来。本文主要针对AMS的启动、相关数据结构、组件管理、进程管理和内存管理进行分析,本文结合四大组件的工作过程文章阅读效果更好,后续会继续补充AMS中的内容。