Activity后生命周期暂停问题

要深入分析为何在 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.threadActivityThread.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);)。如果 ApplicationonCreate 方法中执行了耗时操作,比如初始化大量的第三方 SDK(像广告 SDK、推送 SDK 等),或者进行数据库的复杂初始化操作,会阻塞主线程,使得后续 ActivityonCreate 方法无法及时被调用。
  • 主线程消息队列堵塞 :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 生命周期延迟的具体原因,并针对性地进行优化和解决。

相关推荐
zhangphil16 分钟前
Android Coil 3拦截器Interceptor计算单次请求耗时,Kotlin
android·kotlin
DokiDoki之父39 分钟前
多线程—飞机大战排行榜功能(2.0版本)
android·java·开发语言
用户2018792831673 小时前
强制关闭生命周期延时的Activity实现思路
android
用户2018792831673 小时前
浅析:WindowManager添加的 View 的事件传递机制
android
顾林海3 小时前
从"面条代码"到"精装别墅":Android MVPS架构的逆袭之路
android·面试·架构
白夜4 小时前
Android 开发工程常识
android
编程乐学4 小时前
原创模板--基于 Android 开发的驾考训练App
android·android studio·大作业·移动端开发·安卓移动开发·驾考宝典·驾考app
阿赵3D4 小时前
Unity2022打包安卓报错的奇葩问题
android·unity·安卓