Android Activity启动流程源码分析

最近大体分析了一把 Activity 启动的流程,趁着今晚刚🏊完精神状态好,把以前记录的写成文章。java

开门见山,咱们直接点进去看 Activity 的 startActivity , 最终,咱们都会走到 startActivityForResult 这个方法,咱们能够发现关键的代码:web

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。app

全局搜索 extends IActivityManager 咱们能够发现进行通讯的就是 ActivityManagerService , 查看 startActivity 最终能够走到 ActivityStartstartActivityMayWait 方法。咱们抽取它的关键代码:socket

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

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

最终咱们会走到 startActivityLocked 方法,并走到 startActivityspa

这里咱们会看到不少对于不一样的 ActivityManager 的 状态进行逻辑判断和处理,这里不影响咱们的关键流程,咱们能够继续往下分析, 分析 doPendingActivityLaunchesLocked 方法线程

startActivity(pal.r, pal.sourceRecord, null, null, pal.startFlags, resume, null,
                        null, null /*outRecords*/);
复制代码

最终仍是会走到另外一个重载的 startActivity :3d

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的启动流程作了一个简单的梳理。咱们会发现每一个模块和细节都有几百几百行的代码。很是的复杂。下面的内容有兴趣你们也能够细细探究。

  • 存在的 Activity 是怎么管理的,怎么走 onResume 去恢复的
  • Activity 不一样的 launch mode是怎么处理的
  • zygote fork 新的app进程的细节
  • LoadedApk 是怎么加载 apk 的内容的
  • Activity 初始化完成后,内部是 window 又是怎么初始化而且渲染上 UI 内容的
相关文章
相关标签/搜索