Android Activity——启动过程探索(一)

Activity 系列博客

Activity 生命周期:

activity_lifecycle.png

首先来看一下当Activity启动时,会回调哪些生命周期的方法:

  • 不关闭当前Activity启动流程:
不关闭当前Activity启动流程.jpg
  • 关闭当前Activity启动流程:
关闭当前Activity启动流程.jpg

对于上面的回调过程,我想大部分Android开发者都是知道的,但是对于系统是怎样一步一步来回调这些方法的,可能存在不少疑问。下面我们就通过源码来看看当我们调用 startActivity()finish() 方法时系统是怎样一步步来回调各个方法的。

其实对于每一个生命周期方法的调用,都可以看做是一小步,所以我们的分析就可以比较简单的进行分步:

  1. 当前Activity调用 onPause()
  2. 新的Activity调用 onCreate()
  3. 新的Activity调用 onStart()
  4. 新的Activity调用 onResume()
  5. 当前Activity调用 onStop()
  6. 当前Activity调用 onDestory()【前提是调用了 finish() 方法】

在实际中,除了以上的生命周期方法回调外,还有一些回调方法也是比较重要的(比如:attach()、onRestart()等),就不在单独分析,而是在对应的地方一起分析了。

注意:以下分析过程,源码版本为 Android 10(Api 29),不同Android版本可能有一些差别。

当前Activity调用 onPause() 过程

Activity 启动流程-1. 当前Activity流程 onPause().png

根据上图查看对应的方法:

当我们调用 startActivity() 之后,系统按如下步骤执行:

-> Activity#startActivity()
-> Activity#startActivityForResult()
-> Instrumentation#execStartActivity(activity, mMainThread.getApplicationThread(), mToken, this,intent, requestCode, options)

说明:

  1. mMainThread.getApplicationThread() 返回 ApplicationThread
  2. ApplicationThread 的声明为 ActivityThread.ApplicationThread extends IApplicationThread.Stub

-> ActivityTaskManagerService#startActivity()

说明:

  1. ActivityTaskManagerService 通过 ActivityTaskManager.getService() 获取
  2. ActivityTaskManager.getService() 返回 IActivityTaskManager
  3. ActivityTaskManagerService 的声明为 ActivityTaskManagerService extends IActivityTaskManager.Stub,所以上一步是: ActivityTaskManagerService#startActivity()

-> ActivityTaskManagerService#startActivityAsUser()

说明:

  1. 会多次调用重载方法,这里就看做一步了,最终走到 下一步

-> ActivityStartController#obtainStarter()

说明:

  1. ActivityStartController 通过 getActivityStartController() 方法获取
  2. ActivityStartController.obtainStarter() 方法返回的是ActivityStarter对象
  3. 然后设置数据,实际调用的都是 ActivityStarter 中的设置数据方法,最终调用 ActivityStarter 的 execute() 方法

具体代码如下:

    getActivityStartController().obtainStarter(intent, "startActivityAsUser")
                .setCaller(caller)
                .setCallingPackage(callingPackage)
                .setResolvedType(resolvedType)
                .setResultTo(resultTo)
                .setResultWho(resultWho)
                .setRequestCode(requestCode)
                .setStartFlags(startFlags)
                .setProfilerInfo(profilerInfo)
                .setActivityOptions(bOptions)
                .setMayWait(userId) // 注意该方法,会将ActivityStarter mRequest.mayWait = true;
                .execute();

-> ActivityStarter#execute()

说明:

  1. 上一步的 setMayWait() 方法 会将 ActivityStarter 中的 mRequest.mayWait 标识置为 true,在 execute() 方法中会通过该标记判断下一步执行的方法

-> ActivityStarter#startActivityMayWait()
-> ActivityStarter#startActivity()

说明:

  1. 会多次调用重载 startActivity() 方法,这里就看做一步了,最终走到 下一步

-> ActivityStarter#startActivityUnchecked()
-> RootActivityContainer#resumeFocusedStacksTopActivities()

说明:

  1. 调用重载无参数方法,由无参数方法调用有参数方法,参数都为null,看做一步,走到下一步

-> ActivityStack#resumeTopActivityUncheckedLocked()
-> ActivityStack#resumeTopActivityInnerLocked()
-> ActivityStack#startPausingLocked()

startPausingLocked() 方法中有如下代码:

mService.getLifecycleManager().scheduleTransaction(prev.app.getThread(),
                    prev.appToken, PauseActivityItem.obtain(prev.finishing, userLeaving,
                            prev.configChangeFlags, pauseImmediately));

说明:

  1. mService.getLifecycleManager() 方法返回的对象是 ClientLifecycleManager,(其中mService 是 ActivityTaskManagerService)
  2. 重点注意方法中的几个参数:
    1. 第一个参数 prev.app.getThread() 获取到的是 IApplicationThread(IApplicationThread 的声明在上面已经说明了)
    2. 第三个参数 PauseActivityItem.obtain(),注意PauseActivityItem类: PauseActivityItem extends ActivityLifecycleItem

-> ClientLifecycleManager#scheduleTransaction(IApplicationThread client, IBinder activityToken,ActivityLifecycleItem stateRequest)

注意 scheduleTransaction() 方法的代码:

final ClientTransaction clientTransaction = transactionWithState(client, activityToken,stateRequest);
scheduleTransaction(clientTransaction);

构建了一个 ClientTransaction 对象 clientTransaction 进行传递

-> ClientLifecycleManager#scheduleTransaction(ClientTransaction transaction)
-> ClientTransaction#schedule()
-> IApplicationThread#scheduleTransaction()

说明:

  1. IApplicationThread就是ActivityThread.ApplicationThread
  2. 在 ActivityThread.ApplicationThread 中直接调用了 ActivityThread.this.scheduleTransaction(transaction),所以最终调用的是 ActivityThread#scheduleTransaction(),但是 ActivityThread 中并没有这个方法,是在其父类 ClientTransactionHandler 中的方法( ActivityThread extends ClientTransactionHandler)

-> ClientTransactionHandler#sendMessage()

说明:

  1. sendMessage() 方法在 ClientTransactionHandler中定义,由子类 ActivityThread 实现

  2. 在sendMessage()方法中传递的 what 是 ActivityThread.H.EXECUTE_TRANSACTION

  3. 在ActivityThread中的handler消息都是由 ActivityThread 内部类 H 负责处理,所以查看 H 类中 handleMessage() 方法对应的处理逻辑

     case EXECUTE_TRANSACTION:
         final ClientTransaction transaction = (ClientTransaction) msg.obj;
         mTransactionExecutor.execute(transaction);
         if (isSystem()) {
             transaction.recycle();
         }
         break;
    
  4. mTransactionExecutor 对象是 TransactionExecutor

-> TransactionExecutor#execute(transaction)

说明:

  1. 参数 transaction 就是上面构建的 ClientTransaction 对象

-> TransactionExecutor#executeLifecycleState(transaction)

final ActivityLifecycleItem lifecycleItem = transaction.getLifecycleStateRequest();
lifecycleItem.execute(mTransactionHandler, token, mPendingActions);

说明:

  1. transaction.getLifecycleStateRequest() 获取到 ActivityLifecycleItem 对象,在这里实际上获取到的就是 PauseActivityItem 对象,上面我们在 ActivityStack#startPausingLocked() 中已经说到了

-> PauseActivityItem#execute()
-> ClientTransactionHandler#handlePauseActivity()

说明:

  1. handlePauseActivity() 方法在 ClientTransactionHandler中定义,由子类 ActivityThread 实现,所以查看 ActivityThread 的 handlePauseActivity()

-> ActivityThread#performPauseActivity()
-> ActivityThread#performPauseActivityIfNeeded()
-> Instrumentation#callActivityOnPause()
-> Activity#performPause()
-> Activity#onPause()

通过以上过程,最终调用了Activity 的 onPause() 回调方法,到此为止,我们启动Activity的第一步,当前Activity的onPause()回调执行过程就完成了。接下来,查看第二步创建新的Activity实例,并执行 onCreate() 回调。

新的Activity调用 onCreate()

Activity 启动流程-2. 新的Activity流程 attach()、onCreate().png

根据上图查看对应的方法:

当我们调用 startActivity() 之后,系统按如下步骤执行:

-> Activity#startActivity()
-> Activity#startActivityForResult()
-> Instrumentation#execStartActivity(activity, mMainThread.getApplicationThread(), mToken, this,intent, requestCode, options)

说明:

  1. mMainThread.getApplicationThread() 返回 ApplicationThread
  2. ApplicationThread 的声明为 ActivityThread.ApplicationThread extends IApplicationThread.Stub

-> ActivityTaskManagerService#startActivity()

说明:

  1. ActivityTaskManagerService 通过 ActivityTaskManager.getService() 获取
  2. ActivityTaskManager.getService() 返回 IActivityTaskManager
  3. ActivityTaskManagerService 的声明为 ActivityTaskManagerService extends IActivityTaskManager.Stub,所以上一步是: ActivityTaskManagerService#startActivity()

-> ActivityTaskManagerService#startActivityAsUser()

说明:

  1. 会多次调用重载方法,这里就看做一步了,最终走到 下一步

-> ActivityStartController#obtainStarter()

说明:

  1. ActivityStartController 通过 getActivityStartController() 方法获取
  2. ActivityStartController.obtainStarter() 方法返回的是ActivityStarter对象
  3. 然后设置数据,实际调用的都是 ActivityStarter 中的设置数据方法,最终调用 ActivityStarter 的 execute() 方法

具体代码如下:

    getActivityStartController().obtainStarter(intent, "startActivityAsUser")
                .setCaller(caller)
                .setCallingPackage(callingPackage)
                .setResolvedType(resolvedType)
                .setResultTo(resultTo)
                .setResultWho(resultWho)
                .setRequestCode(requestCode)
                .setStartFlags(startFlags)
                .setProfilerInfo(profilerInfo)
                .setActivityOptions(bOptions)
                .setMayWait(userId) // 注意该方法,会将ActivityStarter mRequest.mayWait = true;
                .execute();

-> ActivityStarter#execute()

说明:

  1. 上一步的 setMayWait() 方法 会将 ActivityStarter 中的 mRequest.mayWait 标识置为 true,在 execute() 方法中会通过该标记判断下一步执行的方法

-> ActivityStarter#startActivityMayWait()
-> ActivityStarter#startActivity()

说明:

  1. 会多次调用重载 startActivity() 方法,这里就看做一步了,最终走到 下一步

-> ActivityStarter#startActivityUnchecked()
-> RootActivityContainer#resumeFocusedStacksTopActivities()

说明:

  1. 调用重载无参数方法,由无参数方法调用有参数方法,参数都为null,看做一步,走到下一步

-> ActivityStack#resumeTopActivityUncheckedLocked()
-> ActivityStack#resumeTopActivityInnerLocked()
-> ActivityStackSupervisor#startSpecificActivityLocked()
-> ActivityStackSupervisor#realStartActivityLocked()

realStartActivityLocked() 方法中有如下代码:

// Create activity launch transaction.
final ClientTransaction clientTransaction = ClientTransaction.obtain(
        proc.getThread(), r.appToken);

final DisplayContent dc = r.getDisplay().mDisplayContent;
clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
        System.identityHashCode(r), r.info,
        mergedConfiguration.getGlobalConfiguration(),
        mergedConfiguration.getOverrideConfiguration(), r.compat,
        r.launchedFromPackage, task.voiceInteractor, proc.getReportedProcState(),
        r.icicle, r.persistentState, results, newIntents,
        dc.isNextTransitionForward(), proc.createProfilerInfoIfNeeded(),r.assistToken));

mService.getLifecycleManager().scheduleTransaction(clientTransaction);

说明:

  1. mService.getLifecycleManager() 方法返回的对象是 ClientLifecycleManager,(其中mService 是 ActivityTaskManagerService)
  2. 创建 ClientTransaction 对象后,调用了它的 addCallback() 方法,增加了 LaunchActivityItem 对象(LaunchActivityItem extends ClientTransactionItem)

-> ClientLifecycleManager#scheduleTransaction(ClientTransaction transaction)
-> ClientTransaction#schedule()
-> IApplicationThread#scheduleTransaction()

说明:

  1. IApplicationThread就是ActivityThread.ApplicationThread
  2. 在 ActivityThread.ApplicationThread 中直接调用了 ActivityThread.this.scheduleTransaction(transaction),所以最终调用的是 ActivityThread#scheduleTransaction(),但是 ActivityThread 中并没有这个方法,是在其父类 ClientTransactionHandler 中的方法( ActivityThread extends ClientTransactionHandler)

-> ClientTransactionHandler#sendMessage()

说明:

  1. sendMessage() 方法在 ClientTransactionHandler中定义,由子类 ActivityThread 实现

  2. 在sendMessage()方法中传递的 what 是 ActivityThread.H.EXECUTE_TRANSACTION

  3. 在ActivityThread中的handler消息都是由 ActivityThread 内部类 H 负责处理,所以查看 H 类中 handleMessage() 方法对应的处理逻辑

     case EXECUTE_TRANSACTION:
         final ClientTransaction transaction = (ClientTransaction) msg.obj;
         mTransactionExecutor.execute(transaction);
         if (isSystem()) {
             transaction.recycle();
         }
         break;
    
  4. mTransactionExecutor 对象是 TransactionExecutor

-> TransactionExecutor#execute(transaction)

说明:

  1. 参数 transaction 就是上面 realStartActivityLocked() 方法中传递的对象

-> TransactionExecutor#executeCallbacks(transaction)

final ClientTransactionItem item = callbacks.get(i);
item.execute(mTransactionHandler, token, mPendingActions);

说明:

  1. callbacks.get(i) 获取到 ClientTransactionItem 对象,在这里实际上获取到的就是 LaunchActivityItem 对象,是在 realStartActivityLocked() 方法中通过 ClientTransaction 对象的 addCallback() 方法增加的

-> LaunchActivityItem#execute()
-> ClientTransactionHandler#handleLaunchActivity()

说明:

  1. handleLaunchActivity() 方法在 ClientTransactionHandler中定义,由子类 ActivityThread 实现,所以查看 ActivityThread 的 handleLaunchActivity()

-> ActivityThread#performLaunchActivity()

// 通过反射创建Activity对象
java.lang.ClassLoader cl = appContext.getClassLoader();
activity = mInstrumentation.newActivity(cl, component.getClassName(), r.intent);

// Instrumentation.newActivity 方法
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);
}

// getFactory() 返回 AppComponentFactory 对象
// AppComponentFactory.instantiateActivity() 方法通过反射完成类实例对象的创建
public @NonNull Activity instantiateActivity(@NonNull ClassLoader cl, @NonNull String className,
        @Nullable Intent intent)
        throws InstantiationException, IllegalAccessException, ClassNotFoundException {
    return (Activity) cl.loadClass(className).newInstance();
}

-> Instrumentation#newActivity()
-> Activity#attach()
-> Instrumentation#callActivityOnCreate
-> Activity#performCreate()
-> Activity#onCreate()

通过以上过程,最终调用了Activity 的 attach() 和 onCreate() 回调方法,到此为止,我们需要启动的Activity已经完成了对象的创建,并且回调了对应的声明周期方法。到此为止,我们的Activity已经算是正式启动了,只是还需要继续回调其他的声明周期方法以完成对用户可见和可操作的过程。

相关扩展:

ContextImpl的创建

在 ActivityThread#performLaunchActivity() 方法中,Instrumentation.newActivity() 之前通过 createBaseContextForActivity() 方法创建了 ContextImpl 对象

ContextImpl appContext = ContextImpl.createActivityContext(
            this, r.packageInfo, r.activityInfo, r.token, displayId, r.overrideConfig);

// ContextImpl.createActivityContext()
ContextImpl context = new ContextImpl(null, mainThread, packageInfo, activityInfo.splitName,
            activityToken, null, 0, classLoader, null);

Application的创建

在 ActivityThread#performLaunchActivity() 方法中,Instrumentation.newActivity() 创建完 Activity 的实例之后,通过 LoadedApk#makeApplication() 返回了 Application

// LoadedApk.makeApplication()
public Application makeApplication(boolean forceDefaultAppClass,
        Instrumentation instrumentation) {
    if (mApplication != null) {
        return mApplication;
    }

    Application app = null;

    String appClass = mApplicationInfo.className;
    if (forceDefaultAppClass || (appClass == null)) {
        appClass = "android.app.Application";
    }

    try {
        java.lang.ClassLoader cl = getClassLoader();
        if (!mPackageName.equals("android")) {
            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
                    "initializeJavaContextClassLoader");
            initializeJavaContextClassLoader();
            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
        }
        ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
        app = mActivityThread.mInstrumentation.newApplication(
                cl, appClass, appContext);
        appContext.setOuterContext(app);
    } catch (Exception e) {
        
    }
    mActivityThread.mAllApplications.add(app);
    mApplication = app;

    if (instrumentation != null) {
        try {
            instrumentation.callApplicationOnCreate(app);
        } catch (Exception e) {
         
        }
    }
    return app;
}

以上代码,先判断 mApplication 是否为null,如果不为null就直接返回,如果为null,表示我们创建的Activity的LaunchActivity(启动Activity),那么就需要创建Application对象,查看 Instrumentation 的 newApplication() 代码中 Application 的创建过程

// Instrumentation.newApplication()
public Application newApplication(ClassLoader cl, String className, Context context)
        throws InstantiationException, IllegalAccessException, 
        ClassNotFoundException {
    Application app = getFactory(context.getPackageName())
            .instantiateApplication(cl, className);
    app.attach(context);
    return app;
}

// getFactory() 返回 AppComponentFactory 对象
// AppComponentFactory.instantiateApplication() 方法通过反射完成类实例对象的创建
public @NonNull Application instantiateApplication(@NonNull ClassLoader cl,
        @NonNull String className)
        throws InstantiationException, IllegalAccessException, ClassNotFoundException {
    return (Application) cl.loadClass(className).newInstance();
}

通过以上代码,我们看到了Application创建完成之后就马上调用了它的attach(context)方法。

最后通过 Instrumentation.callApplicationOnCreate() 调用 Application 的 onCreate() 方法:

if (instrumentation != null) {
    try {
        instrumentation.callApplicationOnCreate(app);
    } catch (Exception e) {
     
    }
}

public void callApplicationOnCreate(Application app) {
    app.onCreate();
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,602评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,442评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,878评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,306评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,330评论 5 373
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,071评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,382评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,006评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,512评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,965评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,094评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,732评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,283评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,286评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,512评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,536评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,828评论 2 345

推荐阅读更多精彩内容