关于android:面试必备Android-Activity启动流程源码分析

最近大抵剖析了一把 Activity 启动的流程,趁着明天精神状态好,把之前记录的写成文章。

单刀直入,咱们间接点进去看 Activity 的 startActivity , 最终,咱们都会走到 startActivityForResult 这个办法,咱们能够发现要害的代码:

Instrumentation.ActivityResult ar = mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this,intent, requestCode, options);

咱们会发现 Activity 启动其实都通过了一个中转站叫做 Instrumentation, 查看InstrumentationexecStartActivity 办法:

/// 删除了咱们不关怀的局部
try {
    intent.migrateExtraStreamToClipData();
    intent.prepareToLeaveProcess(who);
    int result = ActivityManager.getService().startActivity(whoThread, who.getBasePackageName(), intent,
                     intent.resolveTypeIfNeeded(who.getContentResolver()),token, target != null ? target.mEmbeddedID : null,requestCode, 0, null, options);
    checkStartActivityResult(result, intent);
    } catch (RemoteException e) {
        throw new RuntimeException("Failure from system", e);
    }

咱们会发现这里通过 ActivityManager.getService 在进行通信,进去查看,咱们发现这个 service 其实是一个 IActivityManager.aidl, 阐明这里咱们进行了一次 Android 的 IPC。

全局搜寻 extends IActivityManager 咱们能够发现进行通信的就是 ActivityManagerService , 查看 startActivity 最终能够走到 ActivityStartstartActivityMayWait 办法。咱们抽取它的要害代码:

这部分咱们能够看到依据 intent 解析除了须要的信息,并依据信息去获取了跳转 Activity 的零碎权限。

这一部分代码,则对 intent 进行了解决和判断,咱们根本能够省略这部分非关键逻辑

最终咱们会走到 startActivityLocked 办法,并走到 startActivity

这里咱们会看到很多对于不同的 ActivityManager 的 状态进行逻辑判断和解决,这里不影响咱们的要害流程,咱们能够持续往下剖析, 剖析 doPendingActivityLaunchesLocked 办法

startActivity(pal.r, pal.sourceRecord, null, null, pal.startFlags, resume, null,
                        null, null /*outRecords*/);

最终还是会走到另一个重载的 startActivity :

mService.mWindowManager.deferSurfaceLayout();
            result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
                    startFlags, doResume, options, inTask, outActivity);

查看 startActivityUnchecked : 这里代码逻辑比拟长,咱们查看 ActivityStackSupervisor.resumeFocusedStackTopActivityLocked 办法

持续查看 resumeTopActivityUncheckedLocked 办法, 跟踪到 resumeTopActivityInnerLocked 办法:

这边咱们查看须要 restart 这个 Activity 的简略状况,会调用 ActivityStackSupervisorstartSpecificActivityLocked 办法

这里咱们找到了逻辑的要害:如果 app的线程和过程都存在,咱们会执行 realStartActivityLocked 办法。否则,会持续进行 IPC 告诉 ActivityManagerService 去执行 startProcessLocked

这里咱们差不多能猜到启动逻辑:

  1. 如果启动的是咱们本人 app 过程的 Activity, 那么间接去启动就好了
  2. 如果咱们启动的 Activity 所在的过程不存在,例如:咱们把微信 kill 了,而后跳转微信分享的 Activity,或者咱们点击launch 的微信图标,那么,我么就会走创立新过程的逻辑

那么咱们别离来跟踪这2种状况:

启动本人的Activity

咱们能够找到这段代码的要害逻辑,咱们先剖析下 app.thread 是什么。跟踪进去会发现是一个 IApplicationThread, 能够发现这里又是一个 aidl, 最初咱们能够找到 ApplicationThread

private class ApplicationThread extends IApplicationThread.Stub

这是 ActivityThread 的一个动态外部类,ActivtyThread和启动Activity 相干,那么这个类就应该是和 Application 启动相干。

咱们会发现最初其实发了一个message 到音讯队列中,找到 H 这个 handler 的 handleMessage 办法

case LAUNCH_ACTIVITY: {
    final ActivityClientRecord r = (ActivityClientRecord) msg.obj;
    r.packageInfo = getPackageInfoNoCheck(
    r.activityInfo.applicationInfo, r.compatInfo);
    handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");
} break;

查看 handleLaunchActivity 办法

Activity a = performLaunchActivity(r, customIntent);

performLaunchActivity办法中能够看到

java.lang.ClassLoader cl = appContext.getClassLoader();
activity = mInstrumentation.newActivity(cl, component.getClassName(), r.intent);

这里,咱们发现这里通过 Insteumentation new 了一个 Activity

通过以上代码,咱们还能够发现 new 出 Activity 后的几个步骤

  1. attach Activity, 目测会有初始化 window 的流程
  2. 设置 theme
  3. Activity 的 onCreate 流程
  4. Activity 如果曾经销毁,会去执行 onRestoreInstance ,咱们能够在这里做数据恢复的操作
  5. Activity 在 onCreate 实现后的一些操作

到这里,咱们的 Activity 就启动胜利了

启动新的过程

上面来剖析咱们的第二种状况,咱们能够跟踪到 ActivityManagerService 的 `startProcessLocked 办法, 这个办法最终会走到本人的重载办法:

如果咱们启动的是一个 webview service, 则会走到 startWebView ,这里咱们不思考,所以咱们剖析的是 Process.start 这种初始化一个一般过程的状况。

这个办法最初调用了 ZygoteProcessstart 办法

这里咱们也能够大抵剖析进去,这里就是在通过 socket 通信申请 Zygote 过程 fork 一个子过程,作为新的 APP 过程,具体流程本篇文章临时不做深究。

最终咱们会启动 ActivityThreadmain 办法,持续走到 attach 办法

这里咱们能看到启动主线程的 Looper, 创立零碎 Context 等工作,最终咱们走到 ApplicationThreadbindApplication , 代码这里就不贴了,这里负责了 Application 在初始化的时候的各种工作。包含 LoadedAPKmakeApplication 过程。

if (normalMode) {
    try {
        if (mStackSupervisor.attachApplicationLocked(app)) {
            didSomething = true;
        }
    } catch (Exception e) {
        Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
        badApp = true;
    }
}

这里会发现,失常模式下,咱们走到了 ActivityStackSupervisorattachApplicationLocked 办法,前面就又会和第一局部介绍的一样,走到 realStartActivityLocked 办法,去创立并执行 Activity 的生命周期。

总结

到这里,Activity 的启动流程就大抵梳理进去了。根本就是,Instrumentation 负责 Activity 的创立和直达, ActivityStackSupervisor 负责 Activity的 栈治理。Activity 都通过了 ActviityServerManager 来进行治理。

大略的关系如下图所示:

后续

这里我只是对Activity的启动流程做了一个简略的梳理。咱们会发现每个模块和细节都有几百几百行的代码。齐全吃透还得本人下功夫,看源码,只管这个过程很苦楚。一遍看不懂就再来一遍,跟着博客思路看了不下十遍,致力总会有播种的。

最近收集到一份阿里大神整顿的内部资料,蕴含【Android开发外围常识笔记+2020大厂最新面试题及解析+源码笔记】。如果你是卡在短少学习资源的瓶颈上,那么刚刚好我能帮到你。

敌人们如果有须要,能够我的【Github】浏览下载.

最初送给大家一句话:口头是老子、常识是儿子、发明是孙子。祝福大家能找到各自的办法,实现人生的继续冲破。

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理