Activity相关学习(五)
应用进程与系统服务绑定
attach
- 上篇fork进程后会执行ActivityThread的main方法,然后会执行attach方法。
- ActivityThread是Android应用的主线程,负责管理应用中的Activity、Service等组件的生命周期。
//frameworks/base/core/java/android/app/ActivityThread.java
public static void main(String[] args) {
...
Looper.prepareMainLooper();
...
ActivityThread thread = new ActivityThread();
thread.attach(false, startSeq);
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
...
Looper.loop();
...
}
/*
* 将应用进程与系统服务(如ActivityManagerService)进行绑定,并初始化一些关键组件。
* @param system 表示当前线程是否是系统线程
* @param startSeq
*/
private void attach(boolean system, long startSeq) {
sCurrentActivityThread = this;//静态变量,保存当前ActivityThread实例
mConfigurationController = new ConfigurationController(this);//用于管理应用的配置变化
mSystemThread = system;
//2.2. 非系统进程的处理
if (!system) {
//设置应用的DDM(Dalvik Debug Monitor)名称
android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",
UserHandle.myUserId());
//将应用对象设置为mAppThread的Binder对象
RuntimeInit.setApplicationObject(mAppThread.asBinder());
final IActivityManager mgr = ActivityManager.getService();
try {
//将当前应用进程与系统服务绑定
mgr.attachApplication(mAppThread, startSeq);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
// 3. GC监控
//添加了一个GC监控器,当内存使用量超过最大内存的75%时,会尝试释放一些Activity以减轻内存压力
BinderInternal.addGcWatcher(new Runnable() {
@Override public void run() {
if (!mSomeActivitiesChanged) {
return;
}
Runtime runtime = Runtime.getRuntime();
long dalvikMax = runtime.maxMemory();
long dalvikUsed = runtime.totalMemory() - runtime.freeMemory();
if (dalvikUsed > ((3*dalvikMax)/4)) {
if (DEBUG_MEMORY_TRIM) Slog.d(TAG, "Dalvik max=" + (dalvikMax/1024)
+ " total=" + (runtime.totalMemory()/1024)
+ " used=" + (dalvikUsed/1024));
mSomeActivitiesChanged = false;
try {
ActivityTaskManager.getService().releaseSomeActivities(mAppThread);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
}
});
} else {
// 4. 系统进程的处理
// 设置DDM名称为system_process
android.ddm.DdmHandleAppName.setAppName("system_process",
UserHandle.myUserId());
try {
mInstrumentation = new Instrumentation();
mInstrumentation.basicInit(this);
ContextImpl context = ContextImpl.createAppContext(
this, getSystemContext().mPackageInfo);
mInitialApplication = context.mPackageInfo.makeApplicationInner(true, null);
//调用Application的onCreate方法,完成应用的初始化
mInitialApplication.onCreate();
} catch (Exception e) {
throw new RuntimeException(
"Unable to instantiate Application():" + e.toString(), e);
}
}
//5. 配置变化的回调
//当系统配置(如语言、屏幕方向等)发生变化时,会触发该回调
//更新应用的资源配置,并通过sendMessage方法通知应用配置已变化
ViewRootImpl.ConfigChangedCallback configChangedCallback = (Configuration globalConfig) -> {
synchronized (mResourcesManager) {
if (mResourcesManager.applyConfigurationToResources(globalConfig,
null /* compat */)) {
mConfigurationController.updateLocaleListFromAppContext(
mInitialApplication.getApplicationContext());
final Configuration updatedConfig =
mConfigurationController.updatePendingConfiguration(globalConfig);
if (updatedConfig != null) {
sendMessage(H.CONFIGURATION_CHANGED, globalConfig);
mPendingConfiguration = updatedConfig;
}
}
}
};
ViewRootImpl.addConfigCallback(configChangedCallback);
}
attachApplication
//frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
@Override
public final void attachApplication(IApplicationThread thread, long startSeq) {
if (thread == null) {
throw new SecurityException("Invalid application interface");
}
synchronized (this) {
int callingPid = Binder.getCallingPid();
final int callingUid = Binder.getCallingUid();
final long origId = Binder.clearCallingIdentity();
attachApplicationLocked(thread, callingPid, callingUid, startSeq);
Binder.restoreCallingIdentity(origId);
}
}
- 进程绑定:将应用进程与AMS关联,确保AMS可以管理进程的生命周期。
- 异常处理:在绑定过程中发生异常时,及时清理进程状态并杀死进程。
- 组件启动:绑定成功后,启动进程中的Activity、Service和BroadcastReceiver。
- OOM调整:根据进程的状态调整其OOM值,确保系统内存的合理分配。
/*
* 处理应用进程的绑定请求,将应用进程与AMS关联,并初始化应用的运行环境。
* @param thread 应用进程的IApplicationThread接口,用于与AMS通信
* @param pid 应用进程的PID
* @param callingUid 调用方的UID
* @param startSeq 启动序列号,用于标识应用的启动请求
* return 表示绑定是否成功
*/
private boolean attachApplicationLocked(@NonNull IApplicationThread thread,
int pid, int callingUid, long startSeq) {
// 1 查找目标应用进程记录
// 根据pid从mPidsSelfLocked中查找对应的ProcessRecord
// 如果找到的ProcessRecord与当前请求的callingUid或startSeq不匹配,说明进程记录冲突,需要清理旧的记录
ProcessRecord app;
long startTime = SystemClock.uptimeMillis();
long bindApplicationTimeMillis;
if (pid != MY_PID && pid >= 0) {
synchronized (mPidsSelfLocked) {
app = mPidsSelfLocked.get(pid);
}
if (app != null && (app.getStartUid() != callingUid || app.getStartSeq() != startSeq)) {
...
// // 清理冲突的进程记录
cleanUpApplicationRecordLocked(app, pid, false, false, -1,
true /*replacingPid*/, false /* fromBinderDied */);
removePidLocked(pid, app);
app = null;
}
} else {
app = null;
}
// 2 处理未找到进程记录的情况
// 如果未找到进程记录,尝试从mPendingStarts中查找待启动的进程记录。
//如果找到匹配的记录,调用handleProcessStartedLocked将其标记为已启动。
if (app == null && startSeq > 0) {
final ProcessRecord pending = mProcessList.mPendingStarts.get(startSeq);
if (pending != null && pending.getStartUid() == callingUid
&& pending.getStartSeq() == startSeq
&& mProcessList.handleProcessStartedLocked(pending, pid,
pending.isUsingWrapper(), startSeq, true)) {
app = pending;
}
}
//3 处理无效进程记录
if (app == null) {
...
if (pid > 0 && pid != MY_PID) {
killProcessQuiet(pid);
} else {
try {
//杀死进程(或通知进程退出)
thread.scheduleExit();
} catch (Exception e) {
}
}
return false;
}
// 4 清理旧的进程绑定
// 如果ProcessRecord已经绑定了其他线程,说明旧的进程已失效,调用handleAppDiedLocked清理旧的状态
if (app.getThread() != null) {
handleAppDiedLocked(app, pid, true, true, false /* fromBinderDied */);
}
// 5 绑定应用进程
final String processName = app.processName;
try {
AppDeathRecipient adr = new AppDeathRecipient(
app, pid, thread);//用于监听进程死亡事件
thread.asBinder().linkToDeath(adr, 0);
app.setDeathRecipient(adr);//将AppDeathRecipient绑定到IApplicationThread的Binder对象
} catch (RemoteException e) {
...
return false;
}
//6 初始化进程状态
EventLogTags.writeAmProcBound(app.userId, pid, app.processName);
synchronized (mProcLock) {
app.mState.setCurAdj(ProcessList.INVALID_ADJ);
app.mState.setSetAdj(ProcessList.INVALID_ADJ);
app.mState.setVerifiedAdj(ProcessList.INVALID_ADJ);
mOomAdjuster.setAttachingSchedGroupLSP(app);
app.mState.setForcingToImportant(null);
updateProcessForegroundLocked(app, false, 0, false);
app.mState.setHasShownUi(false);
app.mState.setCached(false);
app.setDebugging(false);
app.setKilledByAm(false);
app.setKilled(false);
app.setUnlocked(StorageManager.isUserKeyUnlocked(app.userId));
}
...
//7 绑定应用
final ProviderInfoList providerList = ProviderInfoList.fromList(providers);
if (app.getIsolatedEntryPoint() != null) {
thread.runIsolatedEntryPoint(
app.getIsolatedEntryPoint(), app.getIsolatedEntryPointArgs());
} else if (instr2 != null) {
thread.bindApplication(processName, appInfo,
app.sdkSandboxClientAppVolumeUuid, app.sdkSandboxClientAppPackage,
providerList,
instr2.mClass,
profilerInfo, instr2.mArguments,
instr2.mWatcher,
instr2.mUiAutomationConnection, testMode,
mBinderTransactionTrackingEnabled, enableTrackAllocation,
isRestrictedBackupMode || !normalMode, app.isPersistent(),
new Configuration(app.getWindowProcessController().getConfiguration()),
app.getCompat(), getCommonServicesLocked(app.isolated),
mCoreSettingsObserver.getCoreSettingsLocked(),
buildSerial, autofillOptions, contentCaptureOptions,
app.getDisabledCompatChanges(), serializedSystemFontMap,
app.getStartElapsedTime(), app.getStartUptime());
} else {
thread.bindApplication(processName, appInfo,
app.sdkSandboxClientAppVolumeUuid, app.sdkSandboxClientAppPackage,
providerList, null, profilerInfo, null, null, null, testMode,
mBinderTransactionTrackingEnabled, enableTrackAllocation,
isRestrictedBackupMode || !normalMode, app.isPersistent(),
new Configuration(app.getWindowProcessController().getConfiguration()),
app.getCompat(), getCommonServicesLocked(app.isolated),
mCoreSettingsObserver.getCoreSettingsLocked(),
buildSerial, autofillOptions, contentCaptureOptions,
app.getDisabledCompatChanges(), serializedSystemFontMap,
app.getStartElapsedTime(), app.getStartUptime());
}
if (profilerInfo != null) {
profilerInfo.closeFd();
profilerInfo = null;
}
...
} catch (Exception e) {
// 8 处理绑定异常
//如果绑定过程中发生异常,记录日志并杀死进程
Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
app.resetPackageList(mProcessStats);
app.unlinkDeathRecipient();
app.killLocked("error during bind", ApplicationExitInfo.REASON_INITIALIZATION_FAILURE,
true);
handleAppDiedLocked(app, pid, false, true, false /* fromBinderDied */);
return false;
}
...
//9 启动Activity、Service等组件
if (normalMode) {
try {
didSomething = mAtmInternal.attachApplication(app.getWindowProcessController());
} catch (Exception e) {
badApp = true;
}
}
if (!badApp) {
try {
didSomething |= mServices.attachApplicationLocked(app, processName);
} catch (Exception e) {
badApp = true;
}
}
if (!badApp) {
updateUidReadyForBootCompletedBroadcastLocked(app.uid);
}
if (!badApp && isPendingBroadcastProcessLocked(pid)) {
try {
didSomething |= sendPendingBroadcastsLocked(app);
} catch (Exception e) {
badApp = true;
}
}
// 10 处理备份代理,如果应用是备份目标,创建备份代理
if (!badApp && backupTarget != null && backupTarget.app == app) {
notifyPackageUse(backupTarget.appInfo.packageName,
PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
try {
thread.scheduleCreateBackupAgent(backupTarget.appInfo,
compatibilityInfoForPackage(backupTarget.appInfo),
backupTarget.backupMode, backupTarget.userId, backupTarget.operationType);
} catch (Exception e) {
badApp = true;
}
}
if (badApp) {
app.killLocked("error during init", ApplicationExitInfo.REASON_INITIALIZATION_FAILURE,
true);
handleAppDiedLocked(app, pid, false, true, false /* fromBinderDied */);
return false;
}
//如果未启动任何组件,更新进程的OOM调整值
if (!didSomething) {
updateOomAdjLocked(app, OomAdjuster.OOM_ADJ_REASON_PROCESS_BEGIN);
}
final HostingRecord hostingRecord = app.getHostingRecord();
String shortAction = getShortAction(hostingRecord.getAction());
//12 记录启动时间
FrameworkStatsLog.write(
FrameworkStatsLog.PROCESS_START_TIME,
app.info.uid,
pid,
app.info.packageName,
FrameworkStatsLog.PROCESS_START_TIME__TYPE__COLD,
app.getStartElapsedTime(),
(int) (bindApplicationTimeMillis - app.getStartUptime()),
(int) (SystemClock.uptimeMillis() - app.getStartUptime()),
hostingRecord.getType(),
hostingRecord.getName(),
shortAction,
HostingRecord.getHostingTypeIdStatsd(hostingRecord.getType()),
HostingRecord.getTriggerTypeForStatsd(hostingRecord.getTriggerType()));
return true;
}
bindApplication
将应用的初始化数据封装为AppBindData对象,并通过消息机制发送给主线程处理
//frameworks/base/core/java/android/app/ActivityThread.java
/*
* 将应用的初始化数据传递给应用进程,并触发应用的启动流程。
* @param processName 应用进程的名称
* @param appInfo 应用的ApplicationInfo,包含应用的包名、UID、目标SDK版本等信息
* @param sdkSandboxClientAppVolumeUuid SDK沙箱信息
* @param sdkSandboxClientAppPackage
* @param providerList Provider 列表
* @param instrumentationName Instrumentation配置
* @param profilerInfo 调用方的UID
* @param debugMode 调试模式
* @param enableBinderTracking 性能分析信息
* return
*/
@Override
public final void bindApplication(String processName, ApplicationInfo appInfo,
String sdkSandboxClientAppVolumeUuid, String sdkSandboxClientAppPackage,
ProviderInfoList providerList, ComponentName instrumentationName,
ProfilerInfo profilerInfo, Bundle instrumentationArgs,
IInstrumentationWatcher instrumentationWatcher,
IUiAutomationConnection instrumentationUiConnection, int debugMode,
boolean enableBinderTracking, boolean trackAllocation,
boolean isRestrictedBackupMode, boolean persistent, Configuration config,
CompatibilityInfo compatInfo, Map services, Bundle coreSettings,
String buildSerial, AutofillOptions autofillOptions,
ContentCaptureOptions contentCaptureOptions, long[] disabledCompatChanges,
SharedMemory serializedSystemFontMap,
long startRequestedElapsedTime, long startRequestedUptime) {
//1 初始化服务缓存
if (services != null) {
...
// 为了将系统服务(如PackageManager、WindowManager等)缓存到ServiceManager中,方便应用进程快速访问
ServiceManager.initServiceCache(services);
}
//2.设置核心配置
//调用setCoreSettings方法,将coreSettings(核心配置)应用到应用进程中。
//coreSettings包含系统的一些全局配置,如字体大小、动画缩放比例等。
setCoreSettings(coreSettings);
//3 封装应用绑定数据,AppBindData是一个数据容器,用于封装应用启动所需的所有信息
AppBindData data = new AppBindData();
data.processName = processName;
data.appInfo = appInfo;
data.sdkSandboxClientAppVolumeUuid = sdkSandboxClientAppVolumeUuid;
data.sdkSandboxClientAppPackage = sdkSandboxClientAppPackage;
data.providers = providerList.getList();
data.instrumentationName = instrumentationName;
data.instrumentationArgs = instrumentationArgs;
data.instrumentationWatcher = instrumentationWatcher;
data.instrumentationUiAutomationConnection = instrumentationUiConnection;
data.debugMode = debugMode;
data.enableBinderTracking = enableBinderTracking;
data.trackAllocation = trackAllocation;
data.restrictedBackupMode = isRestrictedBackupMode;
data.persistent = persistent;
data.config = config;
data.compatInfo = compatInfo;
data.initProfilerInfo = profilerInfo;
data.buildSerial = buildSerial;
data.autofillOptions = autofillOptions;
data.contentCaptureOptions = contentCaptureOptions;
data.disabledCompatChanges = disabledCompatChanges;
data.mSerializedSystemFontMap = serializedSystemFontMap;
data.startRequestedElapsedTime = startRequestedElapsedTime;
data.startRequestedUptime = startRequestedUptime;
//4 发送绑定消息
//调用sendMessage方法,将H.BIND_APPLICATION消息和AppBindData对象发送给主线程。
//主线程的H(Handler)会处理该消息,触发应用的初始化流程。
sendMessage(H.BIND_APPLICATION, data);
}
public void handleMessage(Message msg) {
switch (msg.what) {
case BIND_APPLICATION:
AppBindData data = (AppBindData)msg.obj;
handleBindApplication(data);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
...
handleBindApplication
- 初始化调试和性能分析工具。
- 设置进程名称、包名和资源配置。
- 创建Application对象并调用onCreate方法。
- 安装ContentProvider。
- 处理兼容性配置和网络安全配置。
/*
* 初始化应用进程的环境,包括加载Application类、初始化ContentProvider、设置调试和性能分析工具等。
* @param data AppBindData对象,包含应用启动所需的所有信息(如进程名称、应用信息、Provider列表、调试配置等)
* return
*/
private void handleBindApplication(AppBindData data) {
// 1 初始化调试和性能分析工具
//将UI线程注册为敏感线程,确保其在调试和性能分析中被优先处理
VMRuntime.registerSensitiveThread();
...
if (data.trackAllocation) {
DdmVmInternal.setRecentAllocationsTrackingEnabled(true);
}
// 2 设置进程启动时间
Process.setStartTimes(SystemClock.elapsedRealtime(), SystemClock.uptimeMillis(),
data.startRequestedElapsedTime, data.startRequestedUptime);
//3 处理兼容性配置
AppCompatCallbacks.install(data.disabledCompatChanges);
AppSpecializationHooks.handleCompatChangesBeforeBindingApplication();
//4 初始化配置
mBoundApplication = data;
mConfigurationController.setConfiguration(data.config);
mConfigurationController.setCompatConfiguration(data.config);
mConfiguration = mConfigurationController.getConfiguration();
...
// 5 设置进程名称和包名
Process.setArgV0(data.processName);
android.ddm.DdmHandleAppName.setAppName(data.processName,
data.appInfo.packageName,
UserHandle.myUserId());
...
// 6 初始化性能分析器,启动性能分析
if (mProfiler.profileFd != null) {
mProfiler.startProfiling();
}
// 7 处理目标SDK版本的兼容性
// 如果应用的目标SDK版本较低,调整AsyncTask的默认执行器为线程池
if (data.appInfo.targetSdkVersion <= android.os.Build.VERSION_CODES.HONEYCOMB_MR1) {
AsyncTask.setDefaultExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
...
//8 设置时区和语言
TimeZone.setDefault(null);
LocaleList.setDefault(data.config.getLocales());
//9 初始化系统字体
if (Typeface.ENABLE_LAZY_TYPEFACE_INITIALIZATION) {
try {
Typeface.setSystemFontMap(data.mSerializedSystemFontMap);
} catch (IOException | ErrnoException e) {
Slog.e(TAG, "Failed to parse serialized system font map");
Typeface.loadPreinstalledSystemFontMap();
}
}
//10 更新资源配置
synchronized (mResourcesManager) {
mResourcesManager.applyConfigurationToResources(data.config, data.compatInfo);
mCurDefaultDisplayDpi = data.config.densityDpi;
mConfigurationController.applyCompatConfiguration();
}
...
// Instrumentation info affects the class loader, so load it before
// setting up the app context.
final InstrumentationInfo ii;
if (data.instrumentationName != null) {
ii = prepareInstrumentation(data);
} else {
ii = null;
}
// 11 初始化应用上下文,用于访问应用资源和服务
final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);
mConfigurationController.updateLocaleListFromAppContext(appContext);//更新语言列表
try {
final IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE);
//12 设置HTTP代理
if (b != null) {
final ConnectivityManager cm =
appContext.getSystemService(ConnectivityManager.class);
Proxy.setHttpProxyConfiguration(cm.getDefaultProxy());
}
} finally {
}
//13 初始化图形支持,确保应用能够正确渲染UI
if (!Process.isIsolated()) {
final int oldMask = StrictMode.allowThreadDiskWritesMask();
try {
setupGraphicsSupport(appContext);
} finally {
StrictMode.setThreadPolicyMask(oldMask);
}
} else {
HardwareRenderer.setIsolatedProcess(true);
}
// 14 安装网络安全配置,确保应用能够安全访问网络
NetworkSecurityConfigProvider.install(appContext);
// 15 初始化流量统计
if (!Process.isIsolated()) {
TrafficStats.init(appContext);
}
// 16 初始化Instrumentation
if (ii != null) {
initInstrumentation(ii, data, appContext);
} else {
mInstrumentation = new Instrumentation();
mInstrumentation.basicInit(this);
}
//17 调整堆大小
if ((data.appInfo.flags&ApplicationInfo.FLAG_LARGE_HEAP) != 0) {
dalvik.system.VMRuntime.getRuntime().clearGrowthLimit();//应用启用了大堆模式,清除堆的增长限制
} else {
dalvik.system.VMRuntime.getRuntime().clampGrowthLimit();//限制堆的增长
}
// 18 创建Application对象
Application app;
...
try {
app = data.info.makeApplicationInner(data.restrictedBackupMode, null);
app.setAutofillOptions(data.autofillOptions);
app.setContentCaptureOptions(data.contentCaptureOptions);
sendMessage(H.SET_CONTENT_CAPTURE_OPTIONS_CALLBACK, data.appInfo.packageName);
mInitialApplication = app;
...
// 19 安装ContentProvider
//如果未处于受限备份模式
if (!data.restrictedBackupMode) {
if (!ArrayUtils.isEmpty(data.providers)) {
installContentProviders(app, data.providers);
}
}
// 20.调用Application.onCreate方法,完成应用的初始化
try {
mInstrumentation.onCreate(data.instrumentationArgs);
}
catch (Exception e) {
...
}
try {
mInstrumentation.callApplicationOnCreate(app);
} catch (Exception e) {
...
}
} finally {
...
}
// Preload fonts resources
FontsContract.setApplicationContextForResources(appContext);
if (!Process.isIsolated()) {
try {
final ApplicationInfo info =
getPackageManager().getApplicationInfo(
data.appInfo.packageName,
PackageManager.GET_META_DATA /*flags*/,
UserHandle.myUserId());
if (info.metaData != null) {
final int preloadedFontsResource = info.metaData.getInt(
ApplicationInfo.METADATA_PRELOADED_FONTS, 0);
if (preloadedFontsResource != 0) {
data.info.getResources().preloadFonts(preloadedFontsResource);
}
}
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
}
AMS启动Activity
在上面绑定应用时ActivityManagerService的attachApplicationLocked会启动Activity,最终会执行最后会调用到ActivityTaskSupervisor的realStartActivityLocked方法。
//9 启动Activity、Service等组件
if (normalMode) {
try {
didSomething = mAtmInternal.attachApplication(app.getWindowProcessController());
} catch (Exception e) {
badApp = true;
}
}
realStartActivityLocked
@Override
public boolean test(ActivityRecord r) {
if (r.finishing || !r.showToCurrentUser() || !r.visibleIgnoringKeyguard
|| r.app != null || mApp.mUid != r.info.applicationInfo.uid
|| !mApp.mName.equals(r.processName)) {
return false;
}
try {
if (mTaskSupervisor.realStartActivityLocked(r, mApp,
mTop == r && r.getTask().canBeResumed(r) /* andResume */,
true /* checkConfig */)) {
mHasActivityStarted = true;
}
} catch (RemoteException e) {
Slog.w(TAG, "Exception in new application when starting activity " + mTop, e);
mRemoteException = e;
return true;
}
return false;
}
realStartActivityLocked包括状态检查、配置管理、生命周期状态切换、异常处理等操作。
//frameworks/base/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
/*
* 确保Activity的启动过程是线程安全的,并且处理了与Activity启动相关的各种状态和配置
* @param r 代表要启动的Activity的记录信息,包含了Activity的所有状态和配置
* @param proc 代表与Activity关联的进程控制器,管理进程的生命周期和状态
* @param andResume 指示是否在启动后立即恢复Activity(即将其置于RESUMED状态)
* @param checkConfig 指示是否需要检查配置变化
*/
boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
boolean andResume, boolean checkConfig) throws RemoteException {
//1.启动前的检查
if (!mRootWindowContainer.allPausedActivitiesComplete()) {
// 在启动新Activity之前,系统会检查是否有其他Activity正在暂停。
// 如果有,系统会跳过当前Activity的启动,直到所有Activity都完成暂停操作
// 这是为了避免在系统状态不稳定时启动新Activity
return false;
}
final Task task = r.getTask();//代表一个任务栈,通常包含一组相关的Activity
final Task rootTask = task.getRootTask();//RootTask是任务栈的根,通常与显示屏幕相关联
beginDeferResume();
// 在启动Activity时,系统会暂停配置的分发,以避免在Activity启动过程中发生配置变化导致的额外开销。
proc.pauseConfigurationDispatch();
try {
//5.Activity的启动准备
r.startFreezingScreenLocked(proc, 0);//在Activity启动时冻结屏幕,防止屏幕闪烁
r.startLaunchTickingLocked();//开始记录Activity启动的时间,用于监控启动性能
r.setProcess(proc);//将Activity与进程控制器关联
//6. 检查是否可以恢复Activity,如果Activity不能通过兼容性检查恢复,则取消恢复操作
if (andResume && !r.canResumeByCompat()) {
andResume = false;
}
r.notifyUnknownVisibilityLaunchedForKeyguardTransition();
if (checkConfig) {
mRootWindowContainer.ensureVisibilityAndConfig(r, r.getDisplayId(),
false /* markFrozenIfConfigChanged */, true /* deferResume */);
}
//7.处理Keyguard(锁屏)状态
//如果Activity在锁屏状态下启动,系统会检查是否需要将其设置为可见。
if (mKeyguardController.checkKeyguardVisibility(r) && r.allowMoveToFront()) {
r.setVisibility(true);
}
//8. 用户ID和UID的检查
final int applicationInfoUid =
(r.info.applicationInfo != null) ? r.info.applicationInfo.uid : -1;
if ((r.mUserId != proc.mUserId) || (r.info.applicationInfo.uid != applicationInfoUid)) {
}
...
// 9. Activity启动事务
final ClientTransaction clientTransaction = ClientTransaction.obtain(
proc.getThread(), r.token);//用于将Activity启动的事务发送到客户端(即Activity所在的进程)
final boolean isTransitionForward = r.isTransitionForward();
final IBinder fragmentToken = r.getTaskFragment().getFragmentToken();
clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
System.identityHashCode(r), r.info,
mergedConfiguration.getGlobalConfiguration(),
mergedConfiguration.getOverrideConfiguration(), r.compat,
r.getFilteredReferrer(r.launchedFromPackage), task.voiceInteractor,
proc.getReportedProcState(), r.getSavedState(), r.getPersistentSavedState(),
results, newIntents, r.takeOptions(), isTransitionForward,
proc.createProfilerInfoIfNeeded(), r.assistToken, activityClientController,
r.shareableActivityToken, r.getLaunchedFromBubble(), fragmentToken));
// 10. 设置Activity的生命周期状态
//根据andResume参数决定Activity启动后的生命周期状态。如果andResume为true,则设置为RESUMED状态,否则设置为PAUSED状态。
final ActivityLifecycleItem lifecycleItem;
if (andResume) {
lifecycleItem = ResumeActivityItem.obtain(isTransitionForward,
r.shouldSendCompatFakeFocus());
} else {
lifecycleItem = PauseActivityItem.obtain();
}
clientTransaction.setLifecycleStateRequest(lifecycleItem);
//11. 调度事务,将事务调度到客户端进程,触发Activity的启动
mService.getLifecycleManager().scheduleTransaction(clientTransaction);
...
} catch (RemoteException e) {
//12. 处理异常
//如果Activity启动失败,系统会尝试重新启动进程并重试。如果第二次启动仍然失败,则放弃并记录错误日志。
if (r.launchFailed) {
...
proc.appDied("2nd-crash");
r.finishIfPossible("2nd-crash", false /* oomAdj */);
return false;
}
r.launchFailed = true;
r.detachFromProcess();
throw e;
}
} finally {
//13. 恢复配置分发
endDeferResume();
proc.resumeConfigurationDispatch();
}
r.launchFailed = false;
// 14. 处理Activity的状态
if (andResume && readyToResume()) {
rootTask.minimalResumeActivityLocked(r);
} else {
...
mRootWindowContainer.executeAppTransitionForAllDisplay();
}
//15. 更新进程状态
// 确保进程的优先级和状态与Activity的状态一致
proc.onStartActivity(mService.mTopProcessState, r.info);
// 16. 启动Setup Activity(如果需要)
// 如果当前任务栈是顶层任务栈,则启动Setup Activity(通常用于系统设置或初始化)
if (mRootWindowContainer.isTopDisplayFocusedRootTask(rootTask)) {
mService.getActivityStartController().startSetupActivity();
}
// 17. 更新服务绑定,更新与Activity绑定的服务,确保它们知道Activity的状态变化
if (r.app != null) {
r.app.updateServiceConnectionActivities();
}
return true;
}
scheduleTransaction
//frameworks/base/services/core/java/com/android/server/wm/ClientLifecycleManager.java
void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
final IApplicationThread client = transaction.getClient();
transaction.schedule();
if (!(client instanceof Binder)) {
transaction.recycle();
}
}
//frameworks\base\core\java\android\app\servertransaction\ClientTransaction.java
//ClientTransaction用于在客户端(ActivityThread)和系统服务(如ActivityManagerService)之间传递事务的机制,通常用于处理Activity的生命周期状态切换、配置更新等操作
public void schedule() throws RemoteException {
mClient.scheduleTransaction(this);
}
//frameworks\base\core\java\android\app\ActivityThread.java
@Override
public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
ActivityThread.this.scheduleTransaction(transaction);
}
被启动的App进程中的binder线程在收到请求后,通过handler向主线程发送EXECUTE_TRANSACTION消息
//frameworks\base\core\java\android\app\ClientTransactionHandler.java
void scheduleTransaction(ClientTransaction transaction) {
transaction.preExecute(this);
sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
}
case EXECUTE_TRANSACTION:
final ClientTransaction transaction = (ClientTransaction) msg.obj;
mTransactionExecutor.execute(transaction);
if (isSystem()) {
transaction.recycle();
}
break;
创建Activity
主线程在收到Message后,通过反射机制创建目标Activity,并回调Activity.onCreate()等方法。
execute
//frameworks\base\core\java\android\app\servertransaction\TransactionExecutorHelper.java
public void execute(ClientTransaction transaction) {
final IBinder token = transaction.getActivityToken();
...
executeCallbacks(transaction);
executeLifecycleState(transaction);
mPendingActions.clear();
if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "End resolving transaction");
}
/*
* 依次执行事务中的回调,并根据回调的执行结果调整Activity的生命周期状态
* @param transaction 包含一组回调(ClientTransactionItem)和最终生命周期状态请求(ActivityLifecycleItem)的事务对象
*/
public void executeCallbacks(ClientTransaction transaction) {
//2. 检查回调列表
final List<ClientTransactionItem> callbacks = transaction.getCallbacks();
if (callbacks == null || callbacks.isEmpty()) {
// 如果事务中没有回调(callbacks为空或为空列表),则直接返回,无需执行任何操作
return;
}
...
//3. 获取ActivityClientRecord
final IBinder token = transaction.getActivityToken();//事务关联的Activity的IBinder标识符
//通过token从mTransactionHandler(通常是ActivityThread)中获取的Activity客户端记录。ActivityClientRecord包含了Activity的运行时状态信息
ActivityClientRecord r = mTransactionHandler.getActivityClient(token);
// 4. 获取最终生命周期状态
final ActivityLifecycleItem finalStateRequest = transaction.getLifecycleStateRequest();//事务中请求的最终生命周期状态(例如RESUMED、PAUSED等)
final int finalState = finalStateRequest != null ? finalStateRequest.getTargetState()
: UNDEFINED;//最终状态的目标值。如果未指定最终状态,则使用UNDEFINED
//5. 确定最后一个需要状态切换的回调
final int lastCallbackRequestingState = lastCallbackRequestingState(transaction);
//6. 遍历回调列表并执行
final int size = callbacks.size();
final int size = callbacks.size();
for (int i = 0; i < size; ++i) {
final ClientTransactionItem item = callbacks.get(i);//当前正在处理的回调
final int postExecutionState = item.getPostExecutionState();//回调执行后期望的Activity生命周期状态
//7. 处理回调的前置状态
//检查当前回调是否需要特定的前置状态
if (item.shouldHaveDefinedPreExecutionState()) {
final int closestPreExecutionState = mHelper.getClosestPreExecutionState(r,
item.getPostExecutionState());//通过mHelper获取与postExecutionState最接近的前置状态
if (closestPreExecutionState != UNDEFINED) {
cycleToPath(r, closestPreExecutionState, transaction);//将Activity的生命周期状态切换到closestPreExecutionState,以确保回调能够在正确的状态下执行
}
}
//8. 执行回调
//执行回调的核心逻辑。例如,如果是LaunchActivityItem,则会创建并启动Activity
item.execute(mTransactionHandler, token, mPendingActions);
//回调执行后的清理或后续操作
item.postExecute(mTransactionHandler, token, mPendingActions);
//9. 更新ActivityClientRecord
if (r == null) {
r = mTransactionHandler.getActivityClient(token);
}
if (postExecutionState != UNDEFINED && r != null) {
final boolean shouldExcludeLastTransition =
i == lastCallbackRequestingState && finalState == postExecutionState;
cycleToPath(r, postExecutionState, shouldExcludeLastTransition, transaction);
}
}
}
execute
//frameworks\base\core\java\android\app\servertransaction\LaunchActivityItem.java
@Override
public void execute(ClientTransactionHandler client, IBinder token,
PendingTransactionActions pendingActions) {
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
ActivityClientRecord r = new ActivityClientRecord(token, mIntent, mIdent, mInfo,
mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mState, mPersistentState,
mPendingResults, mPendingNewIntents, mActivityOptions, mIsForward, mProfilerInfo,
client, mAssistToken, mShareableActivityToken, mLaunchedFromBubble,
mTaskFragmentToken);
client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
handleLaunchActivity
- 核心逻辑: 通过performLaunchActivity方法创建和初始化Activity,并确保其正确启动。
- 配置管理: 确保Activity使用最新的配置信息启动。
- 性能优化: 通过硬件加速和图形环境提示优化启动性能。
- 错误处理: 如果启动失败,通知系统结束Activity。
//frameworks\base\core\java\android\app\ActivityThread.java
/*
* 准备并启动一个Activity,确保其正确初始化并进入运行状态
* @param r 包含要启动的Activity的相关信息(如ActivityInfo、Intent等)
* @param pendingActions 用于保存一些需要在Activity启动后执行的操作(如状态恢复)
* @param customIntent 启动Activity时使用的自定义Intent
* return 返回启动的Activity实例
*/
@Override
public Activity handleLaunchActivity(ActivityClientRecord r,
PendingTransactionActions pendingActions, Intent customIntent) {
// 2. 取消GC调度
// 因为Activity即将启动,系统需要确保内存充足,避免在启动过程中触发GC
unscheduleGcIdler();
mSomeActivitiesChanged = true;
...
// 4. 处理配置更新.
//mConfigurationController: 负责管理Activity的配置(如屏幕方向、语言、字体大小等)。
//确保Activity使用最新的配置信息启动
mConfigurationController.handleConfigurationChanged(null, null);
// 初始化硬件加速渲染
//检查是否启用了硬件加速渲染
//检查Activity是否启用了硬件加速
if (ThreadedRenderer.sRendererEnabled
&& (r.activityInfo.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0) {
//预加载硬件加速渲染所需的资源
HardwareRenderer.preload();
}
//初始化窗口管理器
//全局窗口管理器,负责管理所有窗口(如Activity的窗口)
//确保Activity的窗口能够正确创建和显示
WindowManagerGlobal.initialize();
// 提示图形环境.
GraphicsEnvironment.hintActivityLaunch();
//执行Activity启动
final Activity a = performLaunchActivity(r, customIntent);
//处理启动结果
//启动成功
if (a != null) {
//保存当前的配置信息
r.createdConfig = new Configuration(mConfigurationController.getConfiguration());
reportSizeConfigurations(r);//报告Activity的尺寸配置信息
if (!r.activity.mFinished && pendingActions != null) {
pendingActions.setOldState(r.state);
pendingActions.setRestoreInstanceState(true);
pendingActions.setCallOnPostCreate(true);
}
} else {
// 通知ActivityManagerService结束该Activity,并传递取消结果
ActivityClient.getInstance().finishActivity(r.token, Activity.RESULT_CANCELED,
null /* resultData */, Activity.DONT_FINISH_TASK_WITH_ACTIVITY);
}
return a;
}
performLaunchActivity
- 解析Intent和ComponentName。
- 创建Activity的上下文和实例。
- 初始化Activity的资源、窗口和主题。
- 调用Activity的onCreate方法,启动Activity的生命周期。
- 处理异常情况,确保Activity的正确启动。
/*
* 负责Activity的启动过程
* @param r
* @param customIntent
*/
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
//1. 获取ActivityInfo和PackageInfo
//ActivityInfo包含了Activity的元数据,如包名、类名、主题等
ActivityInfo aInfo = r.activityInfo;
if (r.packageInfo == null) {
r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
Context.CONTEXT_INCLUDE_CODE);
}
//2. 解析ComponentName
ComponentName component = r.intent.getComponent();//用于标识Activity的类名和包名。
if (component == null) {
//如果Intent中没有指定ComponentName,则通过resolveActivity方法解析出目标Activity,并设置到Intent中。
component = r.intent.resolveActivity(
mInitialApplication.getPackageManager());
r.intent.setComponent(component);
}
//3. 处理targetActivity
//如果ActivityInfo中指定了targetActivity,则重新设置ComponentName,指向目标Activity
if (r.activityInfo.targetActivity != null) {
component = new ComponentName(r.activityInfo.packageName,
r.activityInfo.targetActivity);
}
//4. 创建Activity的上下文
ContextImpl appContext = createBaseContextForActivity(r);
//5. 实例化Activity对象
Activity activity = null;
try {
java.lang.ClassLoader cl = appContext.getClassLoader();
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
StrictMode.incrementExpectedActivityCount(activity.getClass());
//6. 设置Intent的ClassLoader,设置Intent中Bundle的类加载器,确保可以正确加载Bundle中的对象
r.intent.setExtrasClassLoader(cl);
r.intent.prepareToEnterProcess(isProtectedComponent(r.activityInfo),
appContext.getAttributionSource());
//7. 处理Activity的状态,确保可以正确恢复Activity的状态
if (r.state != null) {
r.state.setClassLoader(cl);
}
} catch (Exception e) {
...
}
try {
//8. 创建Application对象
//通过LoadedApk(即r.packageInfo)的makeApplicationInner方法创建或获取Application对象。
Application app = r.packageInfo.makeApplicationInner(false, mInstrumentation);
// 9. 将Activity记录添加到mActivities中
// 以便后续可以通过token查找Activity
synchronized (mResourcesManager) {
mActivities.put(r.token, r);
}
if (activity != null) {
CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
Configuration config =
new Configuration(mConfigurationController.getCompatConfiguration());
if (r.overrideConfig != null) {
config.updateFrom(r.overrideConfig);
}
if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "
+ r.activityInfo.name + " with config " + config);
Window window = null;
if (r.mPendingRemoveWindow != null && r.mPreserveWindow) {
window = r.mPendingRemoveWindow;
r.mPendingRemoveWindow = null;
r.mPendingRemoveWindowManager = null;
}
// 10. 配置Activity的资源和窗口
appContext.getResources().addLoaders(
app.getResources().getLoaders().toArray(new ResourcesLoader[0]));
appContext.setOuterContext(activity);
//11. 调用Activity的attach方法
activity.attach(appContext, this, getInstrumentation(), r.token,
r.ident, app, r.intent, r.activityInfo, title, r.parent,
r.embeddedID, r.lastNonConfigurationInstances, config,
r.referrer, r.voiceInteractor, window, r.activityConfigCallback,
r.assistToken, r.shareableActivityToken);
if (customIntent != null) {
activity.mIntent = customIntent;
}
r.lastNonConfigurationInstances = null;
checkAndBlockForNetworkAccess();
activity.mStartedActivity = false;
//12. 设置Activity的主题
int theme = r.activityInfo.getThemeResource();
if (theme != 0) {
activity.setTheme(theme);
}
if (r.mActivityOptions != null) {
activity.mPendingOptions = r.mActivityOptions;
r.mActivityOptions = null;
}
activity.mLaunchedFromBubble = r.mLaunchedFromBubble;
activity.mCalled = false;
//13. 调用Activity的onCreate方法
r.activity = activity;
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
...
}
r.setState(ON_CREATE);
} catch (SuperNotCalledException e) {
throw e;
} catch (Exception e) {
...
}
return activity;
}
newActivity
//frameworks\base\core\java\android\app\Instrumentation.java
public Activity newActivity(ClassLoader cl, String className,
Intent intent)
throws InstantiationException, IllegalAccessException,
ClassNotFoundException {
String pkg = intent != null && intent.getComponent() != null
? intent.getComponent().getPackageName() : null;
return getFactory(pkg).instantiateActivity(cl, className, intent);
}
callActivityOnCreate
//frameworks\base\core\java\android\app\Instrumentation.java
public void callActivityOnCreate(Activity activity, Bundle icicle,
PersistableBundle persistentState) {
prePerformCreate(activity);
activity.performCreate(icicle, persistentState);
postPerformCreate(activity);
}
performCreate
performCreate方法的核心作用是执行Activity的创建逻辑,主要包括:
- 初始化窗口模式:判断是否处于多窗口或画中画模式。
- 调用onCreate方法:触发Activity的生命周期回调。
- 恢复状态:从icicle中恢复Activity的状态和过渡动画。
- 分发事件:通知Fragment和监听器Activity的创建状态。
- 记录日志:通过EventLogTags记录onCreate调用事件。
//frameworks\base\core\java\android\app\Activity.java
final void performCreate(Bundle icicle, PersistableBundle persistentState) {
if (Trace.isTagEnabled(Trace.TRACE_TAG_WINDOW_MANAGER)) {
Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "performCreate:"
+ mComponent.getClassName());
}
//2. 分发Activity预创建事件
//通知监听器Activity即将进入onCreate阶段
//这是一个扩展点,允许在onCreate之前执行一些自定义逻辑
dispatchActivityPreCreated(icicle);
//3. 初始化窗口模式相关状态
mCanEnterPictureInPicture = true;//标记Activity是否支持画中画模式
final int windowingMode = getResources().getConfiguration().windowConfiguration
.getWindowingMode();//从当前资源配置中获取窗口模式
mIsInMultiWindowMode = inMultiWindowMode(windowingMode);//判断是否处于多窗口模式
mIsInPictureInPictureMode = windowingMode == WINDOWING_MODE_PINNED;//判断是否处于画中画模式
mShouldDockBigOverlays = getResources().getBoolean(R.bool.config_dockBigOverlayWindows);//从资源文件中读取配置,决定是否应该停靠大尺寸覆盖窗口
//4. 恢复权限请求状态
restoreHasCurrentPermissionRequest(icicle);
//5. 调用onCreate方法
if (persistentState != null) {
onCreate(icicle, persistentState);
} else {
onCreate(icicle);
}
EventLogTags.writeWmOnCreateCalled(mIdent, getComponentName().getClassName(),
"performCreate");
mActivityTransitionState.readState(icicle);
//8. 设置Activity的可见性
//如果windowNoDisplay为true,则Activity不可见
mVisibleFromClient = !mWindow.getWindowStyle().getBoolean(
com.android.internal.R.styleable.Window_windowNoDisplay, false);
//9. 分发Fragment的onActivityCreated事件
mFragments.dispatchActivityCreated();
//10. 设置Activity过渡选项
//设置Activity进入时的过渡选项(例如转场动画)
mActivityTransitionState.setEnterActivityOptions(this, getActivityOptions());
//11. 分发Activity创建完成事件
dispatchActivityPostCreated(icicle);
Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
}