要深入分析为何在 15:29:55
AMS 启动 MainActivity
后生命周期暂停,直到 15:29:57
才监听到 onCreated
,需要从 Android 系统中 Activity 生命周期管理的核心源码流程入手,主要涉及 ActivityManagerService
(AMS) 、ActivityThread
以及 Handler
机制。以下是具体的源码分析:
1. AMS 启动 Activity 的流程
当 AMS 决定启动一个 Activity 时,会调用 ActivityStackSupervisor.realStartActivityLocked
方法,该方法最终会通过 Binder 机制向应用进程发送 LAUNCH_ACTIVITY
消息。相关源码片段(以 Android 11 为例 ):
java
class ActivityStackSupervisor {
boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
boolean andResume, boolean checkConfig) throws RemoteException {
// 构建启动 Activity 需要的信息
Intent intent = r.intent;
// 通过 Binder 向应用进程发送启动 Activity 的请求
app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
System.identityHashCode(r), r.info,
new Configuration(mService.mConfiguration), r.compat,
r.task.voiceInteractor, app.repProcState, r.icicle,
r.persistentState, results, newIntents, !andResume,
mService.isNextTransitionForward(), profileFile,
profileFd, profileAutoStop, r.assistToken);
return true;
}
}
这里的 app.thread
是 ActivityThread.ApplicationThread
的代理,它是应用进程和 AMS 进行跨进程通信的桥梁。
2. 应用进程接收启动请求
应用进程中的 ActivityThread.ApplicationThread
类继承自 IApplicationThread.Stub
,它会处理 AMS 发送过来的各种指令。当接收到 LAUNCH_ACTIVITY
消息时,会调用 handleLaunchActivity
方法,相关代码如下:
java
class ActivityThread {
private class ApplicationThread extends IApplicationThread.Stub {
@Override
public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo,
IVoiceInteractor voiceInteractor, int procState, Bundle state,
PersistableBundle persistentState, List<ResultInfo> pendingResults,
List<Intent> pendingNewIntents, boolean notResumed, boolean isForward,
String profileName, ParcelFileDescriptor profileFd,
boolean autoStopProfiler, IBinder assistToken) {
updateProcessState(procState, false);
ActivityClientRecord r = new ActivityClientRecord();
// 填充 ActivityClientRecord 相关信息
handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");
}
}
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
// 构建 Activity 实例
Activity a = performLaunchActivity(r, customIntent);
if (a != null) {
r.createdConfig = new Configuration(mConfiguration);
Bundle oldState = r.state;
// 执行 Activity 的 onResume 等后续操作(这里先聚焦 onCreate)
handleResumeActivity(r.token, false, r.isForward,
!r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);
}
}
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
ActivityInfo aInfo = r.activityInfo;
if (r.packageInfo == null) {
r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
Context.CONTEXT_INCLUDE_CODE);
}
ComponentName component = r.intent.getComponent();
if (component == null) {
component = r.intent.resolveActivity(
mInitialApplication.getPackageManager());
r.intent.setComponent(component);
}
// 创建 Activity 实例,这里会调用 Activity 的构造函数
Activity activity = null;
try {
java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
StrictMode.incrementExpectedActivityCount(activity.getClass());
r.intent.setExtrasClassLoader(cl);
r.lastNonConfigurationInstances = null;
} catch (Exception e) {
// 异常处理
}
try {
Application app = r.packageInfo.makeApplication(false, mInstrumentation);
if (activity != null) {
Context appContext = createBaseContextForActivity(r, activity);
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.configCallback,
r.assistToken);
if (customIntent != null) {
activity.mIntent = customIntent;
}
r.lastNonConfigurationInstances = null;
// 调用 Activity 的 onCreate 方法
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
r.activity = activity;
}
r.setState(ON_CREATE);
} catch (SuperNotCalledException e) {
throw e;
} catch (Exception e) {
// 异常处理
}
return activity;
}
}
从上述代码可知,在 performLaunchActivity
方法中会调用 mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState)
来触发 Activity 的 onCreate
方法。
3. 可能导致生命周期暂停的原因分析
结合源码流程,导致从 15:29:55
启动到 15:29:57
才监听到 onCreated
的原因可能有以下几种:
(1)系统资源竞争
- CPU 资源 :如果系统中存在其他高优先级的进程或任务占用了大量 CPU 资源,应用进程的线程可能无法及时获取 CPU 时间片来处理 AMS 发送的
LAUNCH_ACTIVITY
消息。例如,后台可能有其他应用正在进行复杂的计算任务(如视频编码、大数据处理),导致 CPU 繁忙,应用进程的ActivityThread
无法及时执行handleLaunchActivity
等后续操作。 - 内存资源 :当系统内存不足时,可能会触发垃圾回收(GC)机制。如果应用进程在启动
MainActivity
时正好触发了 Full GC,会暂停所有线程的执行,从而导致onCreate
方法无法及时被调用。此外,低内存情况下 AMS 也可能会对应用进程进行一些调整,如限制其资源分配,进而影响 Activity 启动流程。
(2)应用进程内的阻塞
- Application 初始化耗时 :在
performLaunchActivity
方法中,会先创建Application
实例并调用其onCreate
方法 (Application app = r.packageInfo.makeApplication(false, mInstrumentation);
)。如果Application
的onCreate
方法中执行了耗时操作,比如初始化大量的第三方 SDK(像广告 SDK、推送 SDK 等),或者进行数据库的复杂初始化操作,会阻塞主线程,使得后续Activity
的onCreate
方法无法及时被调用。 - 主线程消息队列堵塞 :Android 应用的主线程通过
Handler
机制来处理各种消息,包括 Activity 生命周期相关的消息。如果主线程的消息队列中存在大量未处理的耗时消息(例如,之前有通过Handler.postDelayed
发送的长时间执行的任务,或者有复杂的View
绘制任务阻塞了消息队列),那么LAUNCH_ACTIVITY
消息就会在队列中等待,导致onCreate
方法延迟执行。
(3)跨进程通信延迟
AMS 和应用进程之间通过 Binder 进行跨进程通信。如果 Binder 线程池被占满,或者 Binder 通信过程中出现了一些异常(如通信超时、Binder 驱动问题等),会导致 AMS 发送的 LAUNCH_ACTIVITY
消息不能及时到达应用进程,或者应用进程接收到消息后无法及时处理,从而造成 Activity 生命周期的延迟。
4. 如何进一步定位问题
-
查看系统日志 :除了现有的日志,可以通过
adb shell dumpsys activity
查看 AMS 的详细状态,包括 Activity 的启动队列、任务栈信息等,判断是否存在 AMS 层面的延迟或异常。 -
使用 Android Profiler :在 Android Studio 中使用 Android Profiler 工具,监控应用进程的 CPU、内存、线程等情况,查看在启动
MainActivity
期间是否有资源瓶颈或线程阻塞的情况。例如,可以查看主线程的执行轨迹,确定是否被Application.onCreate
或其他操作阻塞。 -
分析应用代码 :仔细检查
Application
类的onCreate
方法以及可能在主线程执行的初始化代码,找出潜在的耗时操作并进行优化。同时,检查是否有不合理的Handler
消息使用导致主线程消息队列堵塞。
通过以上对 Android 源码的分析以及相应的排查手段,可以逐步确定导致 Activity 生命周期延迟的具体原因,并针对性地进行优化和解决。