Android开发经验谈Android开发Android技术知识

Android Activity 启动过程

2018-12-03  本文已影响17人  海阔天空domybest

概要

Android系统中每个app进程都是由zygote进程fork的子进程,fork之后会进行一些进程初始化工作比如binder设置等。。。完成这些初始化工作之后会进入ActivityThread.main方法中,从这里开始会涉及Application、Activity的创建等一些列任务,这篇文章主要细说一下ActivityThread.main及其后续流程。

注:本流程是从api=27源码分析

ActivityThread.main

主要完成主线程Looper的创建开始循环等待事件,创建application,attach到ams中。

...
Looper.prepareMainLooper();

ActivityThread thread = new ActivityThread();        
thread.attach(false);
...
Looper.loop();
...

ActivityThread.attach方法

...
// 将ActivityThread中的成员变量ApplicationThread传递给ams
mgr.attachApplication(mAppThread); 
...
// 值得注意的是在这里还监控了下当前系统内存已经使用的大小是否大于总大小的四分之三,如果超过了,则系统会释放一些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 {
                            mgr.releaseSomeActivities(mAppThread);
                        } catch (RemoteException e) {
                            throw e.rethrowFromSystemServer();
                        }
                    }
                }
            });
...

到此为止我们的流程从app进程转向ams所在进程,ActivityManagerService.attachApplication主要实现在attachApplicationLocked方法中。

private final boolean attachApplicationLocked(IApplicationThread thread,
            int pid) {
...
thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
                        null, null, null, testMode,
                        mBinderTransactionTrackingEnabled, enableTrackAllocation,
                        isRestrictedBackupMode || !normalMode, app.persistent,
                        new Configuration(getGlobalConfiguration()), app.compat,
                        getCommonServicesLocked(app.isolated),
                        mCoreSettingsObserver.getCoreSettingsLocked(),
                        buildSerial);
...
if (normalMode) {
            try {
                if (mStackSupervisor.attachApplicationLocked(app)) {
                    didSomething = true;
                }
            } catch (Exception e) {
                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
                badApp = true;
            }
        }
...

thread.bindApplication 远程调用了app进程中的 ApplicationThread.bindApplication -> ActivityThread.handleBindApplication

private void handleBindApplication(AppBindData data) {
...
// 由 LoadApk 类完成 Application 的创建
Application app = data.info.makeApplication(data.restrictedBackupMode, null);
mInitialApplication = app;
...

我们再回到ams进程中,ActivityManagerService.attachApplication,thread.bindApplication 执行完后,会接着执行下面代码

...
// mStackSupervisor 注意该字段,属于ams成员变量,管理所有 Activity 的所有堆栈的
if (normalMode) {
            try {
                if (mStackSupervisor.attachApplicationLocked(app)) {
                    didSomething = true;
                }
            } catch (Exception e) {
                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
                badApp = true;
            }
        }
...

mStackSupervisor.attachApplicationLocked(app) -> ActivityStackSuperivisor.realStartActivityLocked

final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
            boolean andResume, boolean checkConfig) throws RemoteException {
...
// 又回到了 app进程,ApplicationThread.scheduleLaunchActivity
app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
                    System.identityHashCode(r), r.info,
                    // TODO: Have this take the merged configuration instead of separate global and
                    // override configs.
                    mergedConfiguration.getGlobalConfiguration(),
                    mergedConfiguration.getOverrideConfiguration(), r.compat,
                    r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle,
                    r.persistentState, results, newIntents, !andResume,
                    mService.isNextTransitionForward(), profilerInfo);
...

随后即进入 app 进程中,ActivityThread.handleLaunchActivity,其中调用了两个方法 performLaunchActivity 和 handleResumeActivity 分别对应调用 onCreate 和 onReusme,完成 Activity 的创建及其窗口进入。

ActivityThread.performLaunchActivity

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
...
        try {
            java.lang.ClassLoader cl = appContext.getClassLoader();
            // 利用 ClasssLoader 创建 Activity 实例
            activity = mInstrumentation.newActivity(
                    cl, component.getClassName(), r.intent);
            StrictMode.incrementExpectedActivityCount(activity.getClass());
            r.intent.setExtrasClassLoader(cl);
            r.intent.prepareToEnterProcess();
            if (r.state != null) {
                r.state.setClassLoader(cl);
            }
...

...
                // 利用 Instrumentation 类完成 Activity 的创建,也是在这一步对应回调我们熟悉的 onCreate 方法
                activity.mCalled = false;
                if (r.isPersistable()) {
                    mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
                } else {
                    mInstrumentation.callActivityOnCreate(activity, r.state);
                }
...
}

ActivityThread.handleResumeActivity 中的核心方法 performResumeActivity

r = performResumeActivity(token, clearHide, reason);

ActivityThread.performResumeActivity

public final ActivityClientRecord performResumeActivity(IBinder token,
        boolean clearHide, String reason) {
...
// 最终还是由 Instrumentation 完成 onStart onResume 的回调
r.activity.performResume();
...

由此可见 Activity 的所有生命周期的回调都是由 ActivityThread.mInstrumentation 来完成的

自此已经从 AcitivityThread.main 分析到了 LAUNCHER Activity onCreate onStart onResume,后面的分析待续...

上一篇下一篇

猜你喜欢

热点阅读