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

8次阅读

共计 4268 个字符,预计需要花费 11 分钟才能阅读完成。

最近大抵剖析了一把 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】浏览下载.

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

正文完
 0