一:背景
应用启动速度是用户体验的核心指标之一,无论是Google还是手机厂商还是应用开发者,都在不断地优化启动时间,为了更快一点而努力。想优化应用启动流程,就必须要对应用启动流程有充分的认识与了解。下文将会基于AndroidU的源码,结合systrace,来剖析应用冷启动的全流程。
二:Input事件处理流程
2.1 Input事件处理机制
用户的点击事件,属于Input事件,Input是Android系统常见的事件之一。Input事件的处理核心是InputReader和InputDispatcher,InputReader和InputDispatcher是运行在SystemServer进程中的两个线程,里面各有一个死循环,负责读取和分发Input事件。
按键、屏等驱动会把接收到的input事件存放在/dev/input节点中,InputReader从EventHub中利用Linux的epoll机制监听读取驱动上报的input事件并分发给InputDispatcher,InputDispatcher中把事件放到InboundQueue队列中,然后寻找处理Input事件的目标窗口,并讲事件放入对应目标窗口OutboundQueue队列中,等待通过SocketPair双工信道发送到目标窗口中,发送完毕后会把事件移动到WaitQueue队列中等待事件处理完成并开始计时,如果下次分发事件时,上一次事件在5s内目标窗口没有处理完,就会触发ANR。大致流程如下:
2.1.1 InputReader从EventHub中把Input事件读取出来,执行mQueuedListener.notify发送Input事件。
2.1.2 InputDispatcher接收到notify回调后,更新mInboundQueue。在本身分发事件的循环中检测到mInboundQueue队列中有事件后,对事件进行分装,然后根据KeyEntry找到displayId,把事件传递到displayId对应的窗口。
2.1.3 窗口对应的app,遍历View数,处理Input事件。
这里有几个点需要注意下:
1. InboundQueue("iq")队列中存放着InputDispatcher从InputReader拿到的input事件
2. OutboundQueue("oq")队列中存放着即将要发送给各个窗口的input事件
3. WaitQueue("wq")队列中存放着已经分发给窗口app,但是app还没有处理成功的input事件
4. PendingInputEventQueue("aq")队列中存放着app需要处理的input事件
5. deliverInputEvent 标识着App UI线程被Input事件唤醒
2.2 Systrace中input处理流程
2.2.1 InputReader读取事件
2.2.2 InputDispatcher接收到InputReader读取到的事件,放入InboundQueue即"iq"队列中
2.2.3 InputDispatcher查找目标窗口,把事件放到OutboundQueue即"oq"队列中
2.2.4 InputDispatcher把事件分发给对应窗口(也就是Launcher),把事件放入WaitQueue即"wq"队列中,等待事件处理完成
2.2.5 Launcher接收到Input事件后,先通过enqueueInputEvent函数把事件放入到PendingInputEventQueue即"aq"队列中,并在deliverInputEvent的流程中进行Input事件的分发和处理
2.2.6 Launcher把事件先交给应用界面Window创建时的ViewRootImpl.setView流程中创建的多个不同类型的InputStage中依次进行处理,最后交给ViewPostImeInputStage中进行处理,会从View布局树的根节点DecorView开始遍历View树中的每个子View或者viewGroup进行事件的分发、拦截、处理的逻辑
2.2.7 Input事件在View树中处理完成后会调用finishInputEvent结束应用对Input事件处理逻辑,这里会通过jni调用到native层InputConsumer的sendFinishedSignal函数通知InputDispatcher事件处理完成,把事件从"wq"队列中移除,避免报ANR
2.2.8 Launcher在处理一系列的ACTION_DOWN,ACTION_MOVE一直到ACTION_UP的touch事件后,判断是点击事件,触发View的onClick函数,通过binder调用AMS的startActvity触发进程启动的流程
三:应用进程的创建和启动
3.1 Pause前一个应用
3.1.1 Launcher通过binder调用AMS的startActivity函数后,会执行到ActivityStarter.Request.execute函数,这里会开始记录launchingActivity的systrace tag,即perfetto中看到的Android App Startups开始的地方,即perfetto上看到的进程启动开始的地方
//frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
static class Request {
...
int execute() {
...
//systrace中统计进程启动开始的地方
launchingState = mSupervisor.getActivityMetricsLogger().notifyActivityLaunching(
mRequest.intent, caller, callingUid);
...
res = executeRequest(mRequest);
...
}
}
3.1.2 AMS继续执行startActivity流程,在ActivityStarter.startActivityUnchecked函数中会记录startActivityInner的systrace tag,并调用startActivityInner函数,startActivityInner是真正启动Activity的地方
//frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
int startFlags, ActivityOptions options, Task inTask,
TaskFragment inTaskFragment, @BalCode int balCode,
NeededUriGrants intentGrants, int realCallingUid) {
...
try {
...
try {
Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "startActivityInner");
result = startActivityInner(r, sourceRecord, voiceSession, voiceInteractor,
startFlags, options, inTask, inTaskFragment, balCode,
intentGrants, realCallingUid);
} finally {
Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
startedActivityRootTask = handleStartResult(r, options, result, newTransition,
remoteTransition);
}
} finally {
mService.continueWindowLayout();
}
postStartActivityProcessing(r, result, startedActivityRootTask);
return result;
}
3.1.3 在TaskFragment.resumeTopActivity函数中会调用startPausing来暂定Launcher进程
//frameworks/base/services/core/java/com/android/server/wm/TaskFragment.java
final boolean resumeTopActivity(ActivityRecord prev, ActivityOptions options,
boolean deferPause) {
...
boolean pausing = !deferPause && taskDisplayArea.pauseBackTasks(next);
if (mResumedActivity != null) {
//开始暂停上一个Activity
pausing |= startPausing(mTaskSupervisor.mUserLeaving, false /* uiSleeping */,
next, "resumeTopActivity");
}
...
if (pausing) {
if (next.attachedToProcess()) {//要启动的Activity所属进程已存在
...
} else if (!next.isProcessRunning()) {//要启动的Activity所属进程不存在
final boolean isTop = this == taskDisplayArea.getFocusedRootTask();
//启动进程
mAtmService.startProcessAsync(next, false /* knownToBeDead */, isTop,
isTop ? HostingRecord.HOSTING_TYPE_NEXT_TOP_ACTIVITY
: HostingRecord.HOSTING_TYPE_NEXT_ACTIVITY);
}
...
return true;
}
...
return true;
}
3.1.4 startPausing函数最终对通过Activity.performPause函数调用到Launcher对应Activity的onPause函数,然后调用ActivityRecord.activityPaused函数来通知taskFragment,Activity的pause已经完成,重新执行TaskFragment.resumeTopActivity函数来继续进程启动流程。
回头看4.1.3,这时候pausing变量变成了true,会判断将要启动的Activity所属进程存不存在,如果没有在运行,则会调用mAtmService.startProcessAsync函数进行进程启动工作
//frameworks/base/services/core/java/com/android/server/wm/TaskFragment.java
boolean startPausing(boolean userLeaving, boolean uiSleeping, ActivityRecord resuming,
String reason) {
...
if (prev.attachedToProcess()) {
...
} else {
//分发pause Activity
schedulePauseActivity(prev, userLeaving, pauseImmediately,
false /* autoEnteringPip */, reason);
}
}
}
void schedulePauseActivity(ActivityRecord prev, boolean userLeaving,
boolean pauseImmediately, boolean autoEnteringPip, String reason) {
try {
...
mAtmService.getLifecycleManager().scheduleTransaction(prev.app.getThread(),
prev.token, PauseActivityItem.obtain(prev.finishing, userLeaving,
prev.configChangeFlags, pauseImmediately, autoEnteringPip));
}
...
}
//frameworks/base/core/java/android/app/servertransaction/PauseActivityItem.java
//先执行
public void execute(ClientTransactionHandler client, ActivityClientRecord r,
PendingTransactionActions pendingActions) {
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
client.handlePauseActivity(r, mFinished, mUserLeaving, mConfigChanges, mAutoEnteringPip,
pendingActions, "PAUSE_ACTIVITY_ITEM");
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
//后执行
public void postExecute(ClientTransactionHandler client, IBinder token,
PendingTransactionActions pendingActions) {
...
ActivityClient.getInstance().activityPaused(token);
}
//frameworks/base/core/java/android/app/Activity.java
final void performPause() {
...
dispatchActivityPrePaused();
...
//调用Launcher进程对应Activity的onPause函数
onPause();
...
dispatchActivityPostPaused();
}
//frameworks/base/services/core/java/com/android/server/wm/ActivityRecord.java
void activityPaused(boolean timeout) {
...
try {
//通知系统Activity已经pause完成,可以继续进程启动流程
taskFragment.completePause(true /* resumeNext */, null /* resumingActivity */);
}
...
}
pause Activity的流程在systrace上的体现如下:
3.2 新进程的创建
3.2.1 AMS向zygote发送创建进程的socket请求
接着mAtmService.startProcessAsync函数来看进程创建流程。此函数会经过ATMS-AMS-ProcessList-Process,最终调用到ZygoteProcess.startViaZygote函数,通过socket通信通知zygote fork进程。
注意:ProcessList的startProcessLocked函数,有五个同名的函数,且存在相互调用的逻辑,这里需要根据函数的传参以及函数返回值确认每次具体调用的函数,实在区分不了可以打堆栈确认。
//frameworks/base/services/core/java/com/android/server/am/ProcessList.java
boolean startProcessLocked(...) {
...
try {
...
//进程创建成功会返回对应的pid,并保存在ProcessStartResult中
final Process.ProcessStartResult startResult = startProcess(hostingRecord,
entryPoint, app,
uid, gids, runtimeFlags, zygotePolicyFlags, mountExternal, seInfo,
requiredAbi, instructionSet, invokeWith, startUptime);
//更新zygote创建进程成功后返回的pid到ProcessRecord
handleProcessStartedLocked(app, startResult.pid, startResult.usingWrapper,
startSeq, false);
}
...
}
//frameworks/base/services/core/java/com/android/server/am/ProcessList.java
private Process.ProcessStartResult startProcess(HostingRecord hostingRecord, String entryPoint,
ProcessRecord app, int uid, int[] gids, int runtimeFlags, int zygotePolicyFlags,
int mountExternal, String seInfo, String requiredAbi, String instructionSet,
String invokeWith, long startTime) {
try {
...
//进程启动的systrace tag
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
app.processName);
...
//下面是三种不同类型的创建进程的方式,一般应用都是通过最后一种即Process.start的方式创建
if (hostingRecord.usesWebviewZygote()) {
startResult = startWebView(...);
} else if (hostingRecord.usesAppZygote()) {
final AppZygote appZygote = createAppZygoteForProcessIfNeeded(app);
// We can't isolate app data and storage data as parent zygote already did that.
startResult = appZygote.getProcess().start(...);
} else {
zygotePolicyFlags = ZygoteConfigExt.updateZygotePolicyFlags(
mService.mContext.getContentResolver(), zygotePolicyFlags);
regularZygote = true;
startResult = Process.start(...);
// By now the process group should have been created by zygote.
app.mProcessGroupCreated = true;
}
}
...
}
//frameworks/base/core/java/android/os/Process.java
public static ProcessStartResult start(...) {
return ZYGOTE_PROCESS.start(...);
//frameworks/base/core/java/android/os/ZygoteProcess.java
private Process.ProcessStartResult startViaZygote(...)
throws ZygoteStartFailedEx {
...
synchronized(mLock) {
...
//把创建进程的参数通过socket发送给zygote进程,zygote进程会fork出新的进程并返回pid
return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi),
zygotePolicyFlags,
argsForZygote);
}
...
}
private ZygoteState openZygoteSocketIfNeeded(String abi) throws ZygoteStartFailedEx {
try {
//判断是否已经建立socket连接,如果没有则建立连接
attemptConnectionToPrimaryZygote();
//socket连接已建立
if (primaryZygoteState.matches(abi)) {
return primaryZygoteState;
}
...
}
...
}
private void attemptConnectionToPrimaryZygote() throws IOException {
//如果没有建立连接,则建立socket连接
if (primaryZygoteState == null || primaryZygoteState.isClosed()) {
primaryZygoteState =
ZygoteState.connect(mZygoteSocketAddress, mUsapPoolSocketAddress);
...
}
}
private Process.ProcessStartResult attemptZygoteSendArgsAndGetResult(
ZygoteState zygoteState, String msgStr) throws ZygoteStartFailedEx {
try {
final BufferedWriter zygoteWriter = zygoteState.mZygoteOutputWriter;
final DataInputStream zygoteInputStream = zygoteState.mZygoteInputStream;
//向zygote发送创建进程的请求
zygoteWriter.write(msgStr);
zygoteWriter.flush();
Process.ProcessStartResult result = new Process.ProcessStartResult();
//zygote创建进程成功后返回新进程的pid
result.pid = zygoteInputStream.readInt();
result.usingWrapper = zygoteInputStream.readBoolean();
return result;
}
...
}
3.2.2 Zygote fork进程
ZygoteInit在开机阶段就完成了初始化,会创建一个ZygoteServer对象,在一个单独的线程中进入死循环,等待来自AMS的socket请求。ZygoteServer接收到socket请求后,会调用ZygoteConnection.processCommand函数进行socket请求处理,接着调用Zygote.forkAndSpecialize进行进程的fork创建,创建成功后会返回对应的pid,在ZygoteConnection.handleChildProc中继续处理请求参数。
//frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public static void main(String[] argv) {
ZygoteServer zygoteServer = null;
...
Runnable caller;
try {
...
//做fork前的一些初始化工作,主要是enable DDMS
RuntimeInit.preForkInit();
...
if (!enableLazyPreload) {
...
//提前加载框架通用类和系统资源
preload(bootTimingsTraceLog);
...
}
...
//初始化gc
gcAndFinalize();
...
//创建zygote的服务端对象
zygoteServer = new ZygoteServer(isPrimaryZygote);
...
//在单独的线程中启一个死循环,用来接收AMS的socket请求
caller = zygoteServer.runSelectLoop(abiList);
...
}
...
if (caller != null) {
caller.run();
}
}
//frameworks/base/core/java/com/android/internal/os/ZygoteServer.java
Runnable runSelectLoop(String abiList) {
...
while (true) {
...
try {
...
//获取socket连接
ZygoteConnection connection = peers.get(pollIndex);
//处理socket请求
final Runnable command =
connection.processCommand(this, multipleForksOK);
...
}
...
}
}
//frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java
Runnable processCommand(ZygoteServer zygoteServer, boolean multipleOK) {
try (ZygoteCommandBuffer argBuffer = new ZygoteCommandBuffer(mSocket)) {
while (true) {
...
//调用Zygote的forkAndSpecialize函数进行fork process
pid = Zygote.forkAndSpecialize(...);
...
try {
if (pid == 0) {
...
//pid为0,当前处于新创建的子应用进程中,处理请求参数
return handleChildProc(parsedArgs, childPipeFd,
parsedArgs.mStartChildZygote);
} else {
...
handleParentProc(pid, serverPipeFd);
...
}
}
}
}
}
//frameworks/base/core/java/com/android/internal/os/Zygote.java
static int forkAndSpecialize(...) {
ZygoteHooks.preFork();
//真正fork process的地方是在native层
int pid = nativeForkAndSpecialize(...);
...
}
//frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java
private Runnable handleChildProc(ZygoteArguments parsedArgs,
FileDescriptor pipeFd, boolean isZygote) {
//关闭从父进程zygote继承过来的ZygoteServer服务端地址
closeSocket();
...
if (parsedArgs.mInvokeWith != null) {
...
} else {
if (!isZygote) {
//调用ZygoteInit.zygoteInit继续子应用进程的相关初始化工作
return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,
parsedArgs.mDisabledCompatChanges,
parsedArgs.mRemainingArgs, null /* classLoader */);
} else {
...
}
}
}
3.3 应用进程初始化
设置应用进程默认的java处理机制,启动进程的binder线程池,通过反射调用ActivityThread.attach函数进行Application的初始化工作,创建并启动应用主线程的Looper消息循环机制,接着调用AMS的attachApplication进行Application的初始化,到此进程创建流程就走完了。
PS:进程的binder线程池,这是要注意下,非system_server的binder线程池最大数量是16个,具体定义的位置:frameworks/native/libs/binder/ProcessState.cpp
#define DEFAULT_MAX_BINDER_THREADS 15
//frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public static Runnable zygoteInit(int targetSdkVersion, long[] disabledCompatChanges,
String[] argv, ClassLoader classLoader) {
...
//开始"ZygoteInit"的systrace tag
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit");
RuntimeInit.redirectLogStreams();
//设置应用进程默认的java异常处理机制,可以实现监听、拦截应用进程所有的Java crash的逻辑
RuntimeInit.commonInit();
//JNI调用启动进程的binder线程池,应用进程的binder线程池资源是自己创建的并非从zygote父进程继承的
ZygoteInit.nativeZygoteInit();
//反射创建ActivityThread对象并调用其“main”入口方法
return RuntimeInit.applicationInit(targetSdkVersion, disabledCompatChanges, argv,
classLoader);
}
//frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
protected static Runnable applicationInit(int targetSdkVersion, long[] disabledCompatChanges,
String[] argv, ClassLoader classLoader) {
...
//结束"ZygoteInit"的systrace tag
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
// Remaining arguments are passed to the start class's static main
return findStaticMain(args.startClass, args.startArgs, classLoader);
}
protected static Runnable findStaticMain(String className, String[] argv,
ClassLoader classLoader) {
Class<?> cl;
try {
//反射加载创建ActivityThread类对象
cl = Class.forName(className, true, classLoader);
} catch (ClassNotFoundException ex) {
...
}
Method m;
try {
//反射调用ActivityThread的main方法
m = cl.getMethod("main", new Class[] { String[].class });
} catch (NoSuchMethodException ex) {
...
} catch (SecurityException ex) {
...
}
...
//执行ActivityThread的main方法
return new MethodAndArgsCaller(m, argv);
}
//frameworks/base/core/java/android/app/ActivityThread.java
public static void main(String[] args) {
//开始"ActivityThreadMain"的systrace tag
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");
...
//创建主线程的loop消息循环
Looper.prepareMainLooper();
...
ActivityThread thread = new ActivityThread();
//执行attach继续进行应用初始化的工作
thread.attach(false, startSeq);
...
//结束"ActivityThreadMain"的systrace tag
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
...
//启动主线程的loop消息循环
Looper.loop();
}
private void attach(boolean system, long startSeq) {
...
if (!system) {
...
final IActivityManager mgr = ActivityManager.getService();
try {
//调用attachApplication进行Application的初始化
mgr.attachApplication(mAppThread, startSeq);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
...
}
}
新进程的创建在systrace上体现如下:
四:Application的初始化及Activity的启动
4.1 Application的创建及初始化
在ActivityThread.handleBindApplication初始化过程中,在应用主线程中主要完成以下工作:
- 根据AMS传入的ApplicationInfo信息创建应用APK对应的LoadedApk对象
- 创建应用Application的Context对象
- 调用LoadedApk的makeApplicationInner函数,创建应用的Application对象
//frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
public final void attachApplication(IApplicationThread thread, long startSeq) {
...
synchronized (this) {
...
attachApplicationLocked(thread, callingPid, callingUid, startSeq);
...
}
}
private void attachApplicationLocked(@NonNull IApplicationThread thread,
int pid, int callingUid, long startSeq) {
...
try {
if (app.getIsolatedEntryPoint() != null) {
...
} else if (instr2 != null) {
//调用应用进程ActivityThread.ApplicationThread.bindApplication接口
thread.bindApplication(...);
}
...
//更新LRU进程列表
updateLruProcessLocked(app, false, null);
...
}
}
//frameworks/base/core/java/android/app/ActivityThread.java
private class ApplicationThread extends IApplicationThread.Stub {
public final void bindApplication(...) {
...
//向应用进程主线程Handler发送BIND_APPLICATION消息
sendMessage(H.BIND_APPLICATION, data);
}
}
class H extends Handler {
public void handleMessage(Message msg) {
...
switch (msg.what) {
...
case BIND_APPLICATION:
//开始"bindApplication"的systrace tag
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
...
//在应用主线程执行handleBindApplication初始化动作
handleBindApplication(data);
//结束"bindApplication"的systrace tag
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
...
}
}
}
private void handleBindApplication(AppBindData data) {
...
//创建应用的LoadedApk对象
data.info = getPackageInfo(data.appInfo, mCompatibilityInfo, null /* baseLoader */,
false /* securityViolation */, true /* includeCode */,
false /* registerPackage */, isSdkSandbox);
...
final IActivityManager mgr = ActivityManager.getService();
//创建应用Application的Context,触发Art虚拟机加载应用APK的Dex文件到内存中,并加载应用APK的Resource资源
final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);
...
try {
//调用LoadedApk的makeApplicationInner函数,创建应用的Application对象
app = data.info.makeApplicationInner(data.restrictedBackupMode, null);
...
mgr.finishAttachApplication(mStartSeq);
catch (RemoteException ex) {
...
}
}
//frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
private void finishAttachApplicationInner(long startSeq, int uid, int pid) {
...
synchronized (this) {
...
if (normalMode) {
try {
//继续执行启动应用Activity的流程
didSomething = mAtmInternal.attachApplication(app.getWindowProcessController());
} catch (Exception e) {
...
}
}
if (!badApp) {
try {
//继续执行启动应用Service的流程
didSomething |= mServices.attachApplicationLocked(app, processName);
...
} catch (Exception e) {
...
}
}
if (!badApp) {
try {
for (BroadcastQueue queue : mBroadcastQueues) {
//继续执行启动应用roadcast的流程
didSomething |= queue.onApplicationAttachedLocked(app);
}
...
} catch (BroadcastDeliveryFailedException e) {
...
}
}
...
}
}
4.1.1 创建应用APK对应的LoadedApk对象
//frameworks/base/core/java/android/app/ActivityThread.java
private LoadedApk getPackageInfo(ApplicationInfo aInfo, CompatibilityInfo compatInfo,
ClassLoader baseLoader, boolean securityViolation, boolean includeCode,
boolean registerPackage, boolean isSdkSandbox) {
...
packageInfo =
new LoadedApk(this, aInfo, compatInfo, baseLoader,
securityViolation, includeCode
&& (aInfo.flags & ApplicationInfo.FLAG_HAS_CODE) != 0, registerPackage);
...
}
4.1.2 创建Application的Context对象
4.1.2.1 应用dex文件的加载
在创建Application的Context对象后,会尝试获取加载apk对应的资源文件,这里最终会触发ART加载应用的dex文件(ART加载dex文件的过程后续完善)
//frameworks/base/core/java/android/app/ContextImpl.java
static ContextImpl createAppContext(ActivityThread mainThread, LoadedApk packageInfo,
String opPackageName) {
if (packageInfo == null) throw new IllegalArgumentException("packageInfo");
//new一个Application的Context对象
ContextImpl context = new ContextImpl(null, mainThread, packageInfo,
ContextParams.EMPTY, null, null, null, null, null, 0, null, opPackageName);
//获取apk对应的资源文件
context.setResources(packageInfo.getResources());
context.mContextType = isSystemOrSystemUI(context) ? CONTEXT_TYPE_SYSTEM_OR_SYSTEM_UI
: CONTEXT_TYPE_NON_UI;
...
return context;
}
//frameworks/base/core/java/android/app/LoadedApk.java
public Resources getResources() {
if (mResources == null) {
...
//通过getClassLoader()创建类加载器ClassLoader对象并触发Art虚拟机执行OpenDexFilesFromOat动作加载应用APK的Dex文件
mResources = ResourcesManager.getInstance().getResources(null, mResDir,
splitPaths, mLegacyOverlayDirs, mOverlayPaths,
mApplicationInfo.sharedLibraryFiles, null, null, getCompatibilityInfo(),
getClassLoader(), null);
}
return mResources;
}
//frameworks/base/core/java/android/app/LoadedApk.java
public ClassLoader getClassLoader() {
synchronized (mLock) {
if (mClassLoader == null) {
createOrUpdateClassLoaderLocked(null /*addedPaths*/);
}
return mClassLoader;
}
}
//frameworks/base/core/java/android/app/LoadedApk.java
private void createOrUpdateClassLoaderLocked(List<String> addedPaths) {
...
//寻找apk的资源文件路径保存在zipPaths中,寻找apk的库文件路径保存在libPaths中
makePaths(mActivityThread, isBundledApp, mApplicationInfo, zipPaths, libPaths);
...
//如果应用没有包含可执行代码(即应用没有Java 类或其他需要被执行的代码)
if (!mIncludeCode) {
if (mDefaultClassLoader == null) {
StrictMode.ThreadPolicy oldPolicy = allowThreadDiskReads();
//构造默认类加载器时,传入的codePath是null
mDefaultClassLoader = ApplicationLoaders.getDefault().getClassLoader(
"" /* codePath */, mApplicationInfo.targetSdkVersion, isBundledApp,
librarySearchPath, libraryPermittedPath, mBaseClassLoader,
null /* classLoaderName */);
...
}
if (mClassLoader == null) {
mClassLoader = mAppComponentFactory.instantiateClassLoader(mDefaultClassLoader,
new ApplicationInfo(mApplicationInfo));
}
return;
}
...
if (mDefaultClassLoader == null) {
...
//构造默认类加载器,触发art虚拟机加载dex文件
mDefaultClassLoader = ApplicationLoaders.getDefault().getClassLoaderWithSharedLibraries(
zip, mApplicationInfo.targetSdkVersion, isBundledApp, librarySearchPath,
libraryPermittedPath, mBaseClassLoader,
mApplicationInfo.classLoaderName, sharedLibraries.first, nativeSharedLibraries,
sharedLibraries.second);
...
}
...
if (mClassLoader == null) {
//赋值给mClassLoader对象
mClassLoader = mAppComponentFactory.instantiateClassLoader(mDefaultClassLoader,
new ApplicationInfo(mApplicationInfo));
}
}
//frameworks/base/core/java/android/app/ApplicationLoaders.java
ClassLoader getClassLoaderWithSharedLibraries(...) {
return getClassLoader(...);
}
//frameworks/base/core/java/android/app/ApplicationLoaders.java
private ClassLoader getClassLoader(...) {
...
synchronized (mLoaders) {
...
//创建PathClassLoader加载应用APK的Dex类,并增加相应的systrace tag
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, zip);
ClassLoader loader = ClassLoaderFactory.createClassLoader(
zip, null, parent, classLoaderName, sharedLibraries,
null /*sharedLibrariesLoadedAfterApp*/);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
...
}
}
//frameworks/base/core/java/com/android/internal/os/ClassLoaderFactory.java
public static ClassLoader createClassLoader(String dexPath,
String librarySearchPath, ClassLoader parent, String classloaderName,
List<ClassLoader> sharedLibraries, List<ClassLoader> sharedLibrariesLoadedAfter) {
//通过new的方式创建ClassLoader对象,最终会触发art虚拟机加载APK的dex文件
ClassLoader[] arrayOfSharedLibraries = (sharedLibraries == null)
? null
: sharedLibraries.toArray(new ClassLoader[sharedLibraries.size()]);
ClassLoader[] arrayOfSharedLibrariesLoadedAfterApp = (sharedLibrariesLoadedAfter == null)
? null
: sharedLibrariesLoadedAfter.toArray(
new ClassLoader[sharedLibrariesLoadedAfter.size()]);
if (isPathClassLoaderName(classloaderName)) {
return new PathClassLoader(dexPath, librarySearchPath, parent, arrayOfSharedLibraries,
arrayOfSharedLibrariesLoadedAfterApp);
} else if (isDelegateLastClassLoaderName(classloaderName)) {
...
}
}
4.1.2.2 应用资源的加载
在创建Resources对象过程中加载了应用的资源文件,加载资源文件最终是通过JNI调用Native层的系统system/lib/libandroidfw.so库中的相关C函数实现对APK文件压缩包的解析与加载
//frameworks/base/core/java/android/app/LoadedApk.java
public Resources getResources() {
if (mResources == null) {
...
mResources = ResourcesManager.getInstance().getResources(null, mResDir,
splitPaths, mLegacyOverlayDirs, mOverlayPaths,
mApplicationInfo.sharedLibraryFiles, null, null, getCompatibilityInfo(),
getClassLoader(), null);
}
return mResources;
}
//frameworks/base/core/java/android/app/ResourcesManager.java
public Resources getResources(...) {
try {
//开始"ResourcesManager#getResources"的systrace tag
Trace.traceBegin(Trace.TRACE_TAG_RESOURCES, "ResourcesManager#getResources");
...
//activityToken为getResources传入的第一个参数,此处为null,走else
if (activityToken != null) {
...
} else {
//创建资源文件
resources = createResources(key, classLoader, assetsSupplier);
}
return resources;
} finally {
//结束"ResourcesManager#getResources"的systrace tag
Trace.traceEnd(Trace.TRACE_TAG_RESOURCES);
}
}
//frameworks/base/core/java/android/app/ResourcesManager.java
private Resources createResources(@NonNull ResourcesKey key, @NonNull ClassLoader classLoader,
@Nullable ApkAssetsSupplier apkSupplier) {
synchronized (mLock) {
...
//执行创建Resources资源对象
ResourcesImpl resourcesImpl = findOrCreateResourcesImplForKeyLocked(key, apkSupplier);
...
return createResourcesLocked(classLoader, resourcesImpl, key.mCompatInfo);
}
}
//frameworks/base/core/java/android/app/ResourcesManager.java
private @Nullable ResourcesImpl findOrCreateResourcesImplForKeyLocked(
@NonNull ResourcesKey key, @Nullable ApkAssetsSupplier apkSupplier) {
...
if (impl == null) {
impl = createResourcesImpl(key, apkSupplier);
...
}
return impl;
}
//frameworks/base/core/java/android/app/ResourcesManager.java
private @Nullable ResourcesImpl createResourcesImpl(@NonNull ResourcesKey key,
@Nullable ApkAssetsSupplier apkSupplier) {
//构造AssetManager对象
final AssetManager assets = createAssetManager(key, apkSupplier);
...
//构造ResourcesImpl对象
final ResourcesImpl impl = new ResourcesImpl(assets, displayMetrics, config, daj);
...
return impl;
}
//frameworks/base/core/java/android/app/ResourcesManager.java
private @Nullable AssetManager createAssetManager(@NonNull final ResourcesKey key,
@Nullable ApkAssetsSupplier apkSupplier) {
final AssetManager.Builder builder = new AssetManager.Builder();
final ArrayList<ApkKey> apkKeys = extractApkKeys(key);
for (int i = 0, n = apkKeys.size(); i < n; i++) {
final ApkKey apkKey = apkKeys.get(i);
try {
//通过loadApkAssets加载应用的资源文件
builder.addApkAssets(
(apkSupplier != null) ? apkSupplier.load(apkKey) : loadApkAssets(apkKey));
} catch (IOException e) {
...
}
}
...
return builder.build();
}
//frameworks/base/core/java/android/app/ResourcesManager.java
private @NonNull ApkAssets loadApkAssets(@NonNull final ApkKey key) throws IOException {
...
if (key.overlay) {
apkAssets = ApkAssets.loadOverlayFromPath(overlayPathToIdmapPath(key.path), flags);
} else {
//
apkAssets = ApkAssets.loadFromPath(key.path, flags);
}
...
}
//frameworks/base/core/java/android/content/res/ApkAssets.java
public static @NonNull ApkAssets loadFromPath(@NonNull String path, @PropertyFlags int flags,
@Nullable AssetsProvider assets) throws IOException {
return new ApkAssets(FORMAT_APK, path, flags, assets);
}
//frameworks/base/core/java/android/content/res/ApkAssets.java
private ApkAssets(@FormatType int format, @NonNull String path, @PropertyFlags int flags,
@Nullable AssetsProvider assets) throws IOException {
...
//通过JNI调用Native层的系统system/lib/libandroidfw.so库中的相关C函数实现对APK文件压缩包的解析与加载
mNativePtr = nativeLoad(format, path, flags, assets);
...
}
//frameworks/base/core/jni/android_content_res_ApkAssets.cpp
static jlong NativeLoad(JNIEnv* env, jclass /*clazz*/, const format_type_t format,
jstring java_path, const jint property_flags, jobject assets_provider) {
...
switch (format) {
case FORMAT_APK: {
auto assets = MultiAssetsProvider::Create(std::move(loader_assets),
ZipAssetsProvider::Create(path.c_str(),
property_flags));
//加载资源文件
apk_assets = ApkAssets::Load(std::move(assets), property_flags);
break;
}
...
}
...
return CreateGuardedApkAssets(std::move(apk_assets));
}
4.1.3 调用LoadedApk的makeApplicationInner函数,创建应用的Application对象
//frameworks/base/core/java/android/app/LoadedApk.java
private Application makeApplicationInner(boolean forceDefaultAppClass,
Instrumentation instrumentation, boolean allowDuplicateInstances) {
...
//开始"makeApplication"的systrace tag
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "makeApplication");
...
try {
...
//最终通过ClassLoader.loadClass创建Application对象
app = mActivityThread.mInstrumentation.newApplication(
cl, appClass, appContext);
...
} catch (Exception e) {
...
}
...
//结束"makeApplication"的systrace tag
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
...
}
Application的创建即初始化在systrace上体现如下:
4.2 Activity的启动
由5.1可知application创建完成后,会执行AMS.finishAttachApplicationInner函数,在这里执行Activity的启动流程,依次执行Activity的生命周期函数。
4.2.1 Activity.onCreate
在ActivityTaskSupervisor的realStartActivityLocked函数中完成Activity创建流程,主要做了以下工作:
- 创建Activity的context对象
- 通过反射创建Activity对象
- 在Activity的attach的函数中创建PhoneWindow对象,并PhoneWindow设置WindowManager
- 调用应用Activity的onCreate函数
//frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
private void finishAttachApplicationInner(long startSeq, int uid, int pid) {
...
synchronized (this) {
...
if (normalMode) {
try {
didSomething = mAtmInternal.attachApplication(app.getWindowProcessController());
} catch (Exception e) {
...
}
}
}
...
}
//frameworks/base/services/core/java/com/android/server/am/ActivityTaskManagerService.java
final class LocalService extends ActivityTaskManagerInternal {
public boolean attachApplication(WindowProcessController wpc) throws RemoteException {
synchronized (mGlobalLockWithoutBoost) {
...
try {
return mRootWindowContainer.attachApplication(wpc);
}
...
}
}
}
//frameworks/base/services/core/java/com/android/server/am/RootWindowContainer.java
boolean attachApplication(WindowProcessController app) throws RemoteException {
try {
return mAttachApplicationHelper.process(app);
} finally {
...
}
}
//frameworks/base/services/core/java/com/android/server/am/RootWindowContainer.java
private class AttachApplicationHelper implements Consumer<Task>, Predicate<ActivityRecord> {
boolean process(WindowProcessController app) throws RemoteException {
...
if (!mHasActivityStarted) {
ensureActivitiesVisible(null /* starting */, 0 /* configChanges */,
false /* preserveWindows */);
}
return mHasActivityStarted;
}
//frameworks/base/services/core/java/com/android/server/am/RootWindowContainer.java
void ensureActivitiesVisible(ActivityRecord starting, int configChanges,
boolean preserveWindows, boolean notifyClients) {
...
try {
...
display.ensureActivitiesVisible(starting, configChanges, preserveWindows,
notifyClients);
}
...
}
//frameworks/base/services/core/java/com/android/server/wm/DisplayContent.java
void ensureActivitiesVisible(ActivityRecord starting, int configChanges,
boolean preserveWindows, boolean notifyClients) {
...
try {
forAllRootTasks(rootTask -> {
rootTask.ensureActivitiesVisible(starting, configChanges, preserveWindows,
notifyClients);
});
...
}
...
}
//frameworks/base/services/core/java/com/android/server/wm/Task.java
void ensureActivitiesVisible(@Nullable ActivityRecord starting, int configChanges,
boolean preserveWindows, boolean notifyClients) {
...
try {
forAllLeafTasks(task -> {
task.updateActivityVisibilities(starting, configChanges, preserveWindows,
notifyClients);
}, true /* traverseTopToBottom */);
...
}
...
}
//frameworks/base/services/core/java/com/android/server/wm/TaskFragment.java
final void updateActivityVisibilities(@Nullable ActivityRecord starting, int configChanges,
boolean preserveWindows, boolean notifyClients) {
...
try {
mEnsureActivitiesVisibleHelper.process(
starting, configChanges, preserveWindows, notifyClients);
}
...
}
//frameworks/base/services/core/java/com/android/server/wm/TaskFragment.java
private class EnsureVisibleActivitiesConfigHelper implements Predicate<ActivityRecord> {
...
void process(ActivityRecord start, boolean preserveWindow) {
if (start == null || !start.isVisibleRequested()) {
return;
}
reset(preserveWindow);
forAllActivities(this, start, true /* includeBoundary */,
true /* traverseTopToBottom */);
if (mUpdateConfig) {
// Ensure the resumed state of the focus activity if we updated the configuration of
// any activity.
mRootWindowContainer.resumeFocusedTasksTopActivities();
}
}
...
}
//frameworks/base/services/core/java/com/android/server/wm/RootWindowContainer.java
boolean resumeFocusedTasksTopActivities(
Task targetRootTask, ActivityRecord target, ActivityOptions targetOptions,
boolean deferPause) {
...
if (targetRootTask != null && (targetRootTask.isTopRootTaskInDisplayArea()
|| getTopDisplayFocusedRootTask() == targetRootTask)) {
result = targetRootTask.resumeTopActivityUncheckedLocked(target, targetOptions,
deferPause);
}
...
for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
...
display.forAllRootTasks(rootTask -> {
final ActivityRecord topRunningActivity = rootTask.topRunningActivity();
...
if (topRunningActivity.isState(RESUMED)
&& topRunningActivity == rootTask.getDisplayArea().topRunningActivity()) {
...
} else {
//调用ActivityRecord的makeActiveIfNeeded来startActivity
resumedOnDisplay[0] |= topRunningActivity.makeActiveIfNeeded(target);
}
});
}
}
//frameworks/base/services/core/java/com/android/server/wm/Task.java
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options,
boolean deferPause) {
...
resumed[0] = topFragment.resumeTopActivity(prev, options, deferPause);
...
}
//frameworks/base/services/core/java/com/android/server/wm/TaskFragmen.java
final boolean resumeTopActivity(ActivityRecord prev, ActivityOptions options,
boolean deferPause) {
...
mTaskSupervisor.startSpecificActivity(next, true, true);
...
}
//frameworks/base/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
void startSpecificActivity(ActivityRecord r, boolean andResume, boolean checkConfig) {
...
final WindowProcessController wpc =
mService.getProcessController(r.processName, r.info.applicationInfo.uid);
...
if (wpc != null && wpc.hasThread()) {
try {
realStartActivityLocked(r, wpc, andResume, checkConfig);
return;
} catch (RemoteException e) {
...
}
...
} else if (r.intent.isSandboxActivity(mService.mContext)) {
...
}
...
}
//frameworks/base/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
boolean andResume, boolean checkConfig) throws RemoteException {
...
try {
r.startFreezingScreenLocked(proc, 0);
...
clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
...));
...
final ActivityLifecycleItem lifecycleItem;
if (andResume) {
lifecycleItem = ResumeActivityItem.obtain(isTransitionForward,
r.shouldSendCompatFakeFocus());
} else {
lifecycleItem = PauseActivityItem.obtain();
}
clientTransaction.setLifecycleStateRequest(lifecycleItem);
// Schedule transaction.
mService.getLifecycleManager().scheduleTransaction(clientTransaction);
...
}
...
proc.onStartActivity(mService.mTopProcessState, r.info);
...
}
//frameworks/base/core/java/android/app/servertransaction/LaunchActivityItem.java
public void execute(ClientTransactionHandler client, IBinder token,
PendingTransactionActions pendingActions) {
//开始"activityStart"的systrace tag
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
...
client.handleLaunchActivity(r, pendingActions, mDeviceId, null /* customIntent */);
//结束"activityStart"的systrace tag
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
//frameworks/base/core/java/android/app/ActivityThread.java
public Activity handleLaunchActivity(ActivityClientRecord r,
PendingTransactionActions pendingActions, int deviceId, Intent customIntent) {
...
final Activity a = performLaunchActivity(r, customIntent);
...
}
//frameworks/base/core/java/android/app/ActivityThread.java
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
...
//创建Activity的context对象
ContextImpl appContext = createBaseContextForActivity(r);
...
try {
//通过反射创建Activity对象
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
}
...
try {
//创建Application对象
Application app = r.packageInfo.makeApplicationInner(false, mInstrumentation);
if (activity != null) {
...
//初始化Activity resources
appContext.getResources().addLoaders(
app.getResources().getLoaders().toArray(new ResourcesLoader[0]));
...
//调用Activity的attach函数
activity.attach(...);
...
//设置主题
activity.setTheme(theme);
...
//调用Instrumentation.callActivityOnCreate函数
mInstrumentation.callActivityOnCreate(activity, r.state);
...
...
}
//frameworks/base/core/java/android/app/Activity.java
final void attach(...) {
...
//创建PhoneWindow对象
mWindow = new PhoneWindow(this, window, activityConfigCallback);
...
//为PhoneWindow设置WindowManager
mWindow.setWindowManager(
(WindowManager)context.getSystemService(Context.WINDOW_SERVICE),
mToken, mComponent.flattenToString(),
(info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);
...
}
//frameworks/base/core/java/android/app/Instrumentation.java
public void callActivityOnCreate(Activity activity, Bundle icicle) {
...
activity.performCreate(icicle);
...
}
//frameworks/base/core/java/android/app/Activity.java
final void performCreate(Bundle icicle, PersistableBundle persistentState) {
if (Trace.isTagEnabled(Trace.TRACE_TAG_WINDOW_MANAGER)) {
//开始"performCreate:"的systrace tag
Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "performCreate:"
+ mComponent.getClassName());
}
...
//恢复Activity已经申请的权限
restoreHasCurrentPermissionRequest(icicle);
...
//调用应用的onCreate函数
onCreate(icicle);
...
//结束"performCreate:"的systrace tag
Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
}
4.2.2 Activity.onResume
这里主要做了两件事:
- 调用应用Activity的onResume函数
- 执行WindowManager的addView函数开始视图绘制逻辑
//frameworks/base/core/java/android/app/servertransaction/ResumeActivityItem.java
public void execute(ClientTransactionHandler client, ActivityClientRecord r,
PendingTransactionActions pendingActions) {
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityResume");
client.handleResumeActivity(r, true /* finalStateRequest */, mIsForward,
mShouldSendCompatFakeFocus, "RESUME_ACTIVITY");
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
//frameworks/base/core/java/android/app/ActivityThread.java
public void handleResumeActivity(ActivityClientRecord r, boolean finalStateRequest,
boolean isForward, boolean shouldSendCompatFakeFocus, String reason) {
...
//
if (!performResumeActivity(r, finalStateRequest, reason)) {
return;
}
...
if (r.window == null && !a.mFinished && willBeVisible) {
r.window = r.activity.getWindow();
//获取DecorView
View decor = r.window.getDecorView();
...
//获取WindowManager对象
ViewManager wm = a.getWindowManager();
WindowManager.LayoutParams l = r.window.getAttributes();
a.mDecor = decor;
...
if (a.mVisibleFromClient) {
if (!a.mWindowAdded) {
...
//执行WindowManager的addView函数开始视图绘制逻辑
wm.addView(decor, l);
}
...
}
}
...
}
//frameworks/base/core/java/android/app/ActivityThread.java
public boolean performResumeActivity(ActivityClientRecord r, boolean finalStateRequest,
String reason) {
...
try {
//如果是通过startActivityForResult方式启动Activity,这里返回结果
if (r.pendingResults != null) {
deliverResults(r, r.pendingResults, reason);
r.pendingResults = null;
}
//执行Activity的performResume函数
r.activity.performResume(r.startsNotResumed, reason);
...
//把Activity的状态设置成ON_RESUME
r.setState(ON_RESUME);
...
}
...
}
//frameworks/base/core/java/android/app/Activity.java
final void performResume(boolean followedByPause, String reason) {
//开始"performResume:"的systrace tag
if (Trace.isTagEnabled(Trace.TRACE_TAG_WINDOW_MANAGER)) {
Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "performResume:"
+ mComponent.getClassName());
}
...
//调用Instrumentation.callActivityOnResume函数
mInstrumentation.callActivityOnResume(this);
...
//结束"performResume:"的systrace tag
Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
...
}
//frameworks/base/services/core/java/android/app/Instrumentation.java
public void callActivityOnResume(Activity activity) {
...
//调用应用Activity的onResume函数
activity.onResume();
...
}
4.2.3 Activity.onStart
众所周知Activity的启动,生命周期的执行顺序是onCreate/onStart/onReusme,看完上面两小结,大家是否有一个疑问:onStart哪儿去了?带着这个疑问继续往下看看。
Activity的生命周期基本都是通过Transaction来执行的,传入一个开始状态的lifecycle,传入一个结束状态的lifecycle,中间状态的Transaction会在开始和结束中间依次执行。
状态保存的地方是ActivityLifecycleItem
@IntDef(prefix = { "UNDEFINED", "PRE_", "ON_" }, value = {
UNDEFINED,
PRE_ON_CREATE,
ON_CREATE,
ON_START,
ON_RESUME,
ON_PAUSE,
ON_STOP,
ON_DESTROY,
ON_RESTART
})
public static final int UNDEFINED = -1;
public static final int PRE_ON_CREATE = 0;
public static final int ON_CREATE = 1;
public static final int ON_START = 2;
public static final int ON_RESUME = 3;
public static final int ON_PAUSE = 4;
public static final int ON_STOP = 5;
public static final int ON_DESTROY = 6;
public static final int ON_RESTART = 7;
//frameworks/base/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
boolean andResume, boolean checkConfig) throws RemoteException {
...
final ClientTransaction clientTransaction = ClientTransaction.obtain(
proc.getThread(), r.token);
...
//设置Transaction开始的Lifecycle,即ON_CREATE
clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent), ...));
final ActivityLifecycleItem lifecycleItem;
if (andResume) {
lifecycleItem = ResumeActivityItem.obtain(isTransitionForward,
r.shouldSendCompatFakeFocus());
}
clientTransaction.setLifecycleStateRequest(lifecycleItem);
//设置Transaction结束的Lifecycle,即ON_RESUME
mService.getLifecycleManager().scheduleTransaction(clientTransaction);
...
}
//frameworks/base/core/java/android/app/servertransaction/TransactionExecutor.java
public void execute(ClientTransaction transaction) {
...
//执行回调
executeCallbacks(transaction);
executeLifecycleState(transaction);
...
}
//frameworks/base/core/java/android/app/servertransaction/TransactionExecutor.java
public void executeCallbacks(ClientTransaction transaction) {
final List<ClientTransactionItem> callbacks = transaction.getCallbacks();
...
final int size = callbacks.size();
for (int i = 0; i < size; ++i) {
...
if (postExecutionState != UNDEFINED && r != null) {
...
cycleToPath(r, postExecutionState, shouldExcludeLastTransition, transaction);
}
}
}
//frameworks/base/core/java/android/app/servertransaction/TransactionExecutor.java
private void cycleToPath(ActivityClientRecord r, int finish, boolean excludeLastState,
ClientTransaction transaction) {
//获取Lifecycle开始的状态,这是获取到的是ON_CREATE
final int start = r.getLifecycleState();
...
//获取main lifecycle states,也就是开始和结束中间的需要依次执行的transaction数组。这里传入的finish是ON_RESUME
final IntArray path = mHelper.getLifecyclePath(start, finish, excludeLastState);
//依次执行transaction数组
performLifecycleSequence(r, path, transaction);
}
//frameworks/base/core/java/android/app/servertransaction/TransactionExecutorHelper.java
public IntArray getLifecyclePath(int start, int finish, boolean excludeLastState) {
...
if (finish >= start) {
if (start == ON_START && finish == ON_STOP) {
...
} else {
for (int i = start + 1; i <= finish; i++) {
//这里会把ON_START传入mLifecycleSequence中
mLifecycleSequence.add(i);
}
}
...
}
}
//frameworks/base/core/java/android/app/servertransaction/TransactionExecutor.java
private void performLifecycleSequence(ActivityClientRecord r, IntArray path,
ClientTransaction transaction) {
final int size = path.size();
for (int i = 0, state; i < size; i++) {
state = path.get(i);
...
switch (state) {
...
case ON_START:
//这里会调用到ActivityThread的handleStartActivity函数
mTransactionHandler.handleStartActivity(r, mPendingActions,
null /* activityOptions */);
break;
...
}
...
}
}
//frameworks/base/core/java/android/app/ActivityThread.java
public void handleStartActivity(ActivityClientRecord r,
PendingTransactionActions pendingActions, ActivityOptions activityOptions) {
...
activity.performStart("handleStartActivity");
r.setState(ON_START);
...
}
//frameworks/base/core/java/android/app/Activity.java
final void performStart(String reason) {
...
mInstrumentation.callActivityOnStart(this);
...
}
//frameworks/base/core/java/android/app/Instrumentation.java
public void callActivityOnStart(Activity activity) {
//调用应用Activity的onStart函数
activity.onStart();
}
Activity启动流程,在systrace上体现如下:
五:应用界面的绘制
在继续界面绘制的流程之前,这里先说明下一些view、window的概念、相关的基本类以及相互关系,便于理解后面流程。
- View:Android应用用户界面的基本构建块,用于构建用户界面中的各种元素,如按钮、文本框、图像等。
- Window:用于承载应用的用户界面。一个Activity通常对应一个Window,但也可以有多个Window,如dialog等;Window包含一个DecorView,它是View的容器,用于承载应用的内容视图
- PhoneWindow:Window的实现类,负责管理应用窗口的显示、布局、交互等方面的功能;每个Activity都会有一个PhoneWindow对象来管理其所有的Window。在Activity创建过程中的attach函数中会创建一个PhoneWindow对象(详见5.2.1章节)
- DecorView:应用View树的根节点,继承自View,通过它可以找到View树中的任一节点
- WindowManager:继承自ViewManager,提供了View的基本操作方法;其实现类是WindowManagerImpl,在WindowManagerImpl中有一个WindowManagerGlobal类型的变量mGlobal,用来操作View
- WindowManagerGlobal:是一个单例。其内部有三个非常重要的数组:mViews,mRoots,mParams,分别保存View、ViewRootImpl、LayoutParams对象。对于一个View,如果想获取它对应的ViewRootImpl以及LayoutParams,只需要先在mViews数组中通过View找到对应的位置(即数组下标),然后找到mRoots和mParams对应位置的对象即可。三个数组在相同下标保存的对象是一一对应关系
- ViewRootImpl:ViewRootImpl连接View系统和WindowManager系统,负责管理View的绘制、事件处理、布局和与WindowManagerService、InputMethodManager的交互。
相互关系如下图所示:
5.1 ViewRootImpl.setView
由4.2.2可知,界面绘制开始的入口是WindowManager的addView函数,咱们接着来看界面绘制流程。View绘制的主要实现是在ViewRootImpl的setView中,下面说明setView的关键流程
- 根据应用是否有surface,判断是否要开启硬件加速
- 通过requestLayout函数,触发界面绘制(onMeasure/onLayout/onDraw)
- 通过WindowSession的addToDisplayAsUser函数来添加窗口
- 创建WindowInputEventReceiver对象,封装实现窗口接收Input事件的逻辑
- 设置DecorView的parent为ViewRootImpl
//frameworks/base/core/java/android/view/WindowManagerImpl.java
public void addView(@NonNull View view, @NonNull ViewGroup.LayoutParams params) {
applyTokens(params);
mGlobal.addView(view, params, mContext.getDisplayNoVerify(), mParentWindow,
mContext.getUserId());
}
//frameworks/base/core/java/android/view/WindowManagerGlobal.java
public void addView(View view, ViewGroup.LayoutParams params,
Display display, Window parentWindow, int userId) {
...
//初始化wparams
final WindowManager.LayoutParams wparams = (WindowManager.LayoutParams) params;
...
synchronized (mLock) {
...
//初始化root,这里的windowlessSession是null
if (windowlessSession == null) {
root = new ViewRootImpl(view.getContext(), display);
} else {
root = new ViewRootImpl(view.getContext(), display,
windowlessSession, new WindowlessWindowLayout());
}
...
//更新数组
mViews.add(view);
mRoots.add(root);
mParams.add(wparams);
try {
//调用ViewRootImpl的setView函数
root.setView(view, wparams, panelParentView, userId);
}
}
...
}
//frameworks/base/core/java/android/view/ViewRootImpl.java
public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView,
int userId) {
synchronized (this) {
if (mView == null) {
...
//触发界面绘制(onMeasure/onLayout/onDraw)
requestLayout();
//初始化inputChannel
InputChannel inputChannel = null;
if ((mWindowAttributes.inputFeatures
& WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL) == 0) {
inputChannel = new InputChannel();
}
...
try {
...
//添加窗口
res = mWindowSession.addToDisplayAsUser(mWindow, mWindowAttributes,
getHostVisibility(), mDisplay.getDisplayId(), userId,
mInsetsController.getRequestedVisibleTypes(), inputChannel, mTempInsets,
mTempControls, attachedFrame, compatScale);
...
}
...
if (inputChannel != null) {
//封装实现窗口接收Input事件的逻辑
mInputEventReceiver = new WindowInputEventReceiver(inputChannel,
Looper.myLooper());
}
...
//设置DecorView的parent为ViewRootImpl
view.assignParent(this);
}
}
}
}
5.2 ViewRootImpl.requestLayout
咱们接着看requestLayout,这里会先判断更新UI的是不是主线程,只有主线程才允许更新UI。然后会通过Choreographer往主线程消息队列添加CALLBACK_TRAVERSAL绘制类型的待执行消息,最终会通过DisplayEventReceiver的scheduleVsync函数申请Vsync信号。
这里介绍下Choreographer和Vsync
- Choreographer:主要用于协调和同步 UI 绘制相关的操作。它与系统的 VSync(垂直同步)信号进行同步,确保动画的绘制和界面更新在屏幕刷新时进行,避免出现撕裂(tearing)等视觉问题。它在 Android 渲染链路中起到一个承上启下的作用。
承上: 负责接收和处理 App(ViewRootImpl) 的各种更新消息和回调,等到 Vsync 到来的时候统一处理。例如:集中处理Traversal(包括measure、layout、draw等操作) ,判断掉帧情况,记录 CallBack 耗时等。
启下: 负责请求和接收 Vsync 信号。
请求 Vsync:通过FrameDisplayEventReceiver.scheduleVsync()。
接收 Vsync 事件回调:通过FrameDisplayEventReceiver.onVsync()。
- Vsync:Vsync信号的全称是Vertical Synchronization(中文名垂直同步),由GPU厂商开发,其基本思路就是在屏幕刷新之前向外提供一个信号。例如屏幕刷新率如果是60Hz,那么每隔1000/60=16.6ms就会发送vsync信号。
//frameworks/base/core/java/android/view/ViewRootImpl.java
public void requestLayout() {
if (!mHandlingLayoutInLayoutRequest) {
...
//检查是否是主线程。只有主线程才可以更新UI
checkThread();
//触发绘制流程
scheduleTraversals();
}
}
//frameworks/base/core/java/android/view/ViewRootImpl.java
void scheduleTraversals() {
...
if (!mTraversalScheduled) {
...
//注意此处会往主线程的MessageQueue消息队列中添加同步栅栏,因为系统绘制消息属于异步消息,需要更高优先级的处理
mTraversalBarrier = mHandler.getLooper().getQueue().postSyncBarrier();
...
//通过Choreographer往主线程消息队列添加CALLBACK_TRAVERSAL绘制类型的待执行消息,用于触发后续UI线程真正实现绘制动作
mChoreographer.postCallback(
Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null);
...
}
...
}
//frameworks/base/core/java/android/view/Choreographer.java
private void postCallbackDelayedInternal(int callbackType,
Object action, Object token, long delayMillis) {
...
synchronized (mLock) {
final long now = SystemClock.uptimeMillis();
//这里传入的delayMillis是0
final long dueTime = now + delayMillis;
//把mTraversalRunnable加入到CallbackQueues中
mCallbackQueues[callbackType].addCallbackLocked(dueTime, action, token);
if (dueTime <= now) {
//请求Vsync信号
scheduleFrameLocked(now);
}
...
}
}
//frameworks/base/core/java/android/view/Choreographer.java
private void scheduleFrameLocked(long now) {
if (!mFrameScheduled) {
mFrameScheduled = true;
if (USE_VSYNC) {
...
if (isRunningOnLooperThreadLocked()) {
//请求Vsync信号
scheduleVsyncLocked();
}
...
}
...
}
}
//frameworks/base/core/java/android/view/Choreographer.java
private void scheduleVsyncLocked() {
try {
Trace.traceBegin(Trace.TRACE_TAG_VIEW, "Choreographer#scheduleVsyncLocked");
//通过DisplayEventReceiver的scheduleVsync函数请求Vsync信号
mDisplayEventReceiver.scheduleVsync();
} finally {
Trace.traceEnd(Trace.TRACE_TAG_VIEW);
}
}
//frameworks/base/core/java/android/view/DisplayEventReceiver.java
public void scheduleVsync() {
...
//通过nativeScheduleVsync函数请求Vsync信号
nativeScheduleVsync(mReceiverPtr);
...
}
5.3 ViewRootImpl.performTraversals
当Vsync信号到来后,会触发Choreographer的FrameDisplayEventReceiver的onVsync函数,执行完毕后,会通过run函数调用doframe函数,doframe会处理丢帧逻辑并触发callback(例如Input、animation、traversal等)。tracersal类型的callback被触发后,会调用到ViewRootImpl的performTraversals函数,这里详细说下该函数做了哪些事情。
- 通过Binder调用WMS的relayoutWindow接口,主要完成的工作:1. 创建SurfaceControl 2. 计算窗口大小 3. 给应用端SurfaceControl赋值 4. 填充WMS计算好的数据返回给应用端
- 从DecorView根节点出发,遍历整个View控件树,完成整个View控件树的measure操作
- 从DecorView根节点出发,遍历整个View控件树,完成整个View控件树的layout操作
- 从DecorView根节点出发,遍历整个View控件树,完成整个View控件树的draw操作
//frameworks/base/core/java/android/view/Choreographer.java
private Choreographer(Looper looper, int vsyncSource, long layerHandle) {
mLooper = looper;
//把TRACE_TAG_VIEW systrace tag和looper绑定
mLooper.setTraceTag(Trace.TRACE_TAG_VIEW);
//初始化FrameHandler,绑定Looper
mHandler = new FrameHandler(looper);
//初始化FrameDisplayEventReceiver,与SurfaceFlinger建立通信用于接收和请求Vsync信号
mDisplayEventReceiver = USE_VSYNC
? new FrameDisplayEventReceiver(looper, vsyncSource, layerHandle)
: null;
mLastFrameTimeNanos = Long.MIN_VALUE;
mFrameIntervalNanos = (long)(1000000000 / getRefreshRate());
//初始化CallbackQueue,数组长度为5
mCallbackQueues = new CallbackQueue[CALLBACK_LAST + 1];
for (int i = 0; i <= CALLBACK_LAST; i++) {
mCallbackQueues[i] = new CallbackQueue();
}
...
}
//frameworks/base/core/java/android/view/Choreographer.java
private final class FrameDisplayEventReceiver extends DisplayEventReceiver
implements Runnable {
public void onVsync(long timestampNanos, long physicalDisplayId, int frame,
VsyncEventData vsyncEventData) {
try {
...
//保存绘制时间、帧数和事件数据
mTimestampNanos = timestampNanos;
mFrame = frame;
mLastVsyncEventData.copyFrom(vsyncEventData);
...
} finally {
Trace.traceEnd(Trace.TRACE_TAG_VIEW);
}
}
@Override
public void run() {
//调用主处理函数doFrame
doFrame(mTimestampNanos, mFrame, mLastVsyncEventData);
}
}
//frameworks/base/core/java/android/view/Choreographer.java
void doFrame(long frameTimeNanos, int frame,
DisplayEventReceiver.VsyncEventData vsyncEventData) {
...
try {
...
synchronized (mLock) {
...
//Vsync信号到来的时间距离现在超过一个帧间隔,即出现了丢帧
if (jitterNanos >= frameIntervalNanos) {
...
if (frameIntervalNanos == 0) {
...
} else {
...
//丢帧超过30帧会打印如下日志,碰到卡顿问题时可以搜到响应关键字看丢帧情况
if (skippedFrames >= SKIPPED_FRAME_WARNING_LIMIT) {
Log.i(TAG, "Skipped " + skippedFrames + " frames! "
+ "The application may be doing too much work on its main "
+ "thread.");
}
...
}
...
}
}
...
//处理Input类型的callback
doCallbacks(Choreographer.CALLBACK_INPUT, frameIntervalNanos);
//处理insets animation类型的callback
doCallbacks(Choreographer.CALLBACK_INSETS_ANIMATION, frameIntervalNanos);
//处理traversal类型的callback,这里会回调到ViewRootImpl,触发view的绘制逻辑
doCallbacks(Choreographer.CALLBACK_TRAVERSAL, frameIntervalNanos);
//处理commit类型的callback
doCallbacks(Choreographer.CALLBACK_COMMIT, frameIntervalNanos);
}
}
//frameworks/base/core/java/android/view/ViewRootImpl.java
final class TraversalRunnable implements Runnable {
@Override
public void run() {
doTraversal();
}
}
//frameworks/base/core/java/android/view/ViewRootImpl.java
void doTraversal() {
if (mTraversalScheduled) {
...
//调用removeSyncBarrier及时移除主线程MessageQueue中的Barrier同步栅栏,以避免主线程发生"假死"
mHandler.getLooper().getQueue().removeSyncBarrier(mTraversalBarrier);
...
performTraversals();
...
}
}
//frameworks/base/core/java/android/view/ViewRootImpl.java
private void performTraversals() {
...
//通过Binder调用WMS的relayoutWindow接口,主要完成的工作:1. 创建SurfaceControl 2. 计算窗口大小 3. 给应用端SurfaceControl赋值 4. 填充WMS计算好的数据返回给应用端
relayoutResult = relayoutWindow(params, viewVisibility, insetsPending);
...
//从DecorView根节点出发,遍历整个View控件树,完成整个View控件树的measure操作
performMeasure(childWidthMeasureSpec, childHeightMeasureSpec);
...
//从DecorView根节点出发,遍历整个View控件树,完成整个View控件树的layout操作
performLayout(lp, mWidth, mHeight);
...
//WMS请求同步
createSyncIfNeeded();
notifyDrawStarted(isInWMSRequestedSync());
...
//从DecorView根节点出发,遍历整个View控件树,完成整个View控件树的draw操作
if (!performDraw() && mActiveSurfaceSyncGroup != null) {
//触发绘制完成回调
mActiveSurfaceSyncGroup.markSyncReady();
}
...
}
//frameworks/base/core/java/android/view/ViewRootImpl.java
private void performMeasure(int childWidthMeasureSpec, int childHeightMeasureSpec) {
//开始记录measure的systrace tag
Trace.traceBegin(Trace.TRACE_TAG_VIEW, "measure");
try {
//完成以DecorView为根节点的整个View树的measure工作,View绘制三部曲的第一步measure
mView.measure(childWidthMeasureSpec, childHeightMeasureSpec);
} finally {
//结束记录measure的systrace tag
Trace.traceEnd(Trace.TRACE_TAG_VIEW);
}
...
}
//frameworks/base/core/java/android/view/ViewRootImpl.java
private void performLayout(WindowManager.LayoutParams lp, int desiredWindowWidth,
int desiredWindowHeight) {
...
//开始记录layout的systrace tag
Trace.traceBegin(Trace.TRACE_TAG_VIEW, "layout");
try {
//完成以DecorView为根节点的整个View树的layout工作,View绘制三部曲的第二步layout
host.layout(0, 0, host.getMeasuredWidth(), host.getMeasuredHeight());
...
} finally {
//结束记录layout的systrace tag
Trace.traceEnd(Trace.TRACE_TAG_VIEW);
}
...
}
//frameworks/base/core/java/android/view/ViewRootImpl.java
private boolean performDraw() {
...
//开始记录draw的systrace tag
Trace.traceBegin(Trace.TRACE_TAG_VIEW, "draw");
...
try {
boolean canUseAsync = draw(fullRedrawNeeded, usingAsyncReport && mSyncBuffer);
...
} finally {
//结束记录draw的systrace tag
Trace.traceEnd(Trace.TRACE_TAG_VIEW);
}
...
}
//frameworks/base/core/java/android/view/ViewRootImpl.java
private boolean draw(boolean fullRedrawNeeded, boolean forceDraw) {
...
//如果开启了硬绘
if (isHardwareEnabled()) {
...
//在Renderthread中做绘制动作(现在绝大部分走硬绘)
mAttachInfo.mThreadedRenderer.draw(mView, mAttachInfo, this);
...
} else {
...
//走软绘流程
if (!drawSoftware(...)) {
...
}
}
...
}
以上过程其实就是view绘制三部曲,在systrace上体现如下:
六:Renderthread的绘制
目前Android 4.X之后系统默认是开启硬件加速的,所以我们重点分析硬件加速条件下的界面渲染流程。
- 从DecorView根节点出发,递归遍历View控件树,记录每个View节点的绘制操作命令,完成绘制操作命令树的构建
- JNI调用同步Java层构建的绘制命令树到Native层的RenderThread渲染线程,并唤醒渲染线程利用OpenGL执行渲染任务
//frameworks/base/core/java/android/view/ThreadedRenderer.java
void draw(View view, AttachInfo attachInfo, DrawCallbacks callbacks) {
...
//从DecorView根节点出发,递归遍历View控件树,记录每个View节点的绘制操作命令,完成绘制操作命令树的构建
updateRootDisplayList(view, callbacks);
...
//JNI调用同步Java层构建的绘制命令树到Native层的RenderThread渲染线程,并唤醒渲染线程利用OpenGL执行渲染任务
int syncResult = syncAndDrawFrame(frameInfo);
...
}
6.1 绘制命令树的构建
- 通过renderNode创建一个RecordingCanvas类型的画布
- 利用RecordingCanvas,在每个子View控件的onDraw绘制函数中调用drawRect等绘制操作时,创建对应的DisplayListOp绘制命令,并缓存记录到其内部的DisplayList持有的DisplayListData中
- 将包含有DisplayListOp绘制命令缓存的DisplayList对象设置填充到RenderNode中
- 将所有DisplayListOp绘制命令填充到RootRenderNode中
//frameworks/base/core/java/android/view/ThreadedRenderer.java
private void updateRootDisplayList(View view, DrawCallbacks callbacks) {
//开始记录"Record View#draw()"的systrace tag
Trace.traceBegin(Trace.TRACE_TAG_VIEW, "Record View#draw()");
//递归子View的updateDisplayListIfDirty实现构建DisplayListOp
updateViewTreeDisplayList(view);
...
if (mRootNodeNeedsUpdate || !mRootNode.hasDisplayList()) {
//获取根View的SkiaRecordingCanvas
RecordingCanvas canvas = mRootNode.beginRecording(mSurfaceWidth, mSurfaceHeight);
try {
...
//利用canvas缓存DisplayListOp绘制命令
canvas.drawRenderNode(view.updateDisplayListIfDirty());
...
} finally {
//将所有DisplayListOp绘制命令填充到RootRenderNode中
mRootNode.endRecording();
}
}
...
//结束记录"Record View#draw()"的systrace tag
Trace.traceEnd(Trace.TRACE_TAG_VIEW);
}
//frameworks/base/core/java/android/view/ThreadedRenderer.java
private void updateViewTreeDisplayList(View view) {
...
//从DecorView根节点出发,开始递归调用每个View树节点的updateDisplayListIfDirty函数
view.updateDisplayListIfDirty();
...
}
//frameworks/base/core/java/android/view/View.java
public RenderNode updateDisplayListIfDirty() {
final RenderNode renderNode = mRenderNode;
...
if ((mPrivateFlags & PFLAG_DRAWING_CACHE_VALID) == 0
|| !renderNode.hasDisplayList()
|| (mRecreateDisplayList)) {
//如果已经有了DisplayList且不需要重新创建DisplayList
if (renderNode.hasDisplayList()
&& !mRecreateDisplayList) {
...
//获取view的DisplayList,DisplayList是一个存储了view绘制所需的绘制命令和属性的数据结构。
dispatchGetDisplayList();
...
return renderNode; // no work needed
}
...
//
if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
//开始记录"HWUI:"的systrace tag
Trace.traceBegin(Trace.TRACE_TAG_VIEW, "HWUI:" + getClass().getName());
}
//返回一个RecordingCanvas类型的画布
final RecordingCanvas canvas = renderNode.beginRecording(width, height);
...
try {
if (layerType == LAYER_TYPE_SOFTWARE) {//软绘
...
} else {//硬绘
...
if ((mPrivateFlags & PFLAG_SKIP_DRAW) == PFLAG_SKIP_DRAW) {
//如果仅仅是ViewGroup,并且自身不用绘制,直接递归子View
dispatchDraw(canvas);
...
} else {
//利用RecordingCanvas,在每个子View控件的onDraw绘制函数中调用drawRect等绘制操作时,创建对应的DisplayListOp绘制命令,并缓存记录到其内部的DisplayList持有的DisplayListData中
draw(canvas);
}
}
} finally {
//将包含有DisplayListOp绘制命令缓存的DisplayList对象设置填充到RenderNode中
renderNode.endRecording();
...
}
if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
//结束记录"HWUI:"的systrace tag
Trace.traceEnd(Trace.TRACE_TAG_VIEW);
}
}
...
}
//frameworks/base/graphics/java/android/graphics/RenderNode.java
public @NonNull RecordingCanvas beginRecording(int width, int height) {
...
//调用RecordingCanvas的obtain函数,new一个RecordingCanvas对象
mCurrentRecordingCanvas = RecordingCanvas.obtain(this, width, height);
return mCurrentRecordingCanvas;
}
//frameworks/base/core/java/android/view/View.java
public void draw(@NonNull Canvas canvas) {
...
//draw content view
onDraw(canvas);
...
//触发子view的draw操作
dispatchDraw(canvas);
...
}
//frameworks/base/graphics/java/android/graphics/RenderNode.java
public void endRecording() {
...
RecordingCanvas canvas = mCurrentRecordingCanvas;
mCurrentRecordingCanvas = null;
//从SkiaRecordingCanvas中获取SkiaDisplayList对象,并把SkiaDisplayList对象填充到RenderNode中
canvas.finishRecording(this);
canvas.recycle();
}
6.2 执行渲染任务
UI线程利用RenderProxy向RenderThread线程发送一个DrawFrameTask任务请求,RenderThread被唤醒,开始渲染。Renderthread主要做了以下工作:
- 递归调用各个子View对应的RenderNode执行prepareTreeImpl函数,实现同步绘制命令树的操作
- 调用OpenGL库API使用GPU,按照构建好的绘制命令完成界面的渲染
- 将前面已经绘制渲染好的图形缓冲区Buffer交给SurfaceFlinger合成和显示
//frameworks/base/graphics/java/android/graphics/HardwareRenderer.java
public int syncAndDrawFrame(@NonNull FrameInfo frameInfo) {
return nSyncAndDrawFrame(mNativeProxy, frameInfo.frameInfo, frameInfo.frameInfo.length);
}
//frameworks/base/libs/hwui/jni/android_graphics_HardwareRenderer.cpp
static int android_view_ThreadedRenderer_syncAndDrawFrame(JNIEnv* env, jobject clazz,
jlong proxyPtr, jlongArray frameInfo,
jint frameInfoSize) {
...
//UI线程利用RenderProxy向RenderThread线程发送一个DrawFrameTask任务请求,RenderThread被唤醒,开始渲染
return proxy->syncAndDrawFrame();
}
//frameworks/base/libs/hwui/renderthread/RenderProxy.cpp
int RenderProxy::syncAndDrawFrame() {
return mDrawFrameTask.drawFrame();
}
//frameworks/base/libs/hwui/renderthread/DrawFrameTask.cpp
int DrawFrameTask::drawFrame() {
...
postAndWait();
...
}
//frameworks/base/libs/hwui/renderthread/DrawFrameTask.cpp
void DrawFrameTask::postAndWait() {
ATRACE_CALL();
//加锁,确保线程安全
AutoMutex _lock(mLock);
//向RenderThread渲染线程的MessageQueue消息队列放入一个待执行任务,以将其唤醒执行run函数
mRenderThread->queue().post([this]() { run(); });
//UI线程进入等待状态
mSignal.wait(mLock);
}
//frameworks/base/libs/hwui/renderthread/DrawFrameTask.cpp
void DrawFrameTask::run() {
...
//帧渲染绘制任务的systrace tag
ATRACE_FORMAT("DrawFrames %" PRId64, vsyncId);
...
{
...
//将UI线程构建的DisplayListOp绘制命令树同步到RenderThread渲染线程
canUnblockUiThread = syncFrameState(info);
...
}
...
//同步完成,解锁UI线程
if (canUnblockUiThread) {
unblockUiThread();
}
...
if (CC_LIKELY(canDrawThisFrame)) {
//执行绘制操作
context->draw(solelyTextureViewUpdates);
} else {
...
}
...
}
//frameworks/base/libs/hwui/renderthread/DrawFrameTask.cpp
bool DrawFrameTask::syncFrameState(TreeInfo& info) {
...
//同步绘制命令树
mContext->prepareTree(info, mFrameInfo, mSyncQueued, mTargetNode);
...
}
//frameworks/base/libs/hwui/renderthread/CanvasContext.cpp
void CanvasContext::prepareTree(TreeInfo& info, int64_t* uiFrameInfo, int64_t syncQueued,
RenderNode* target) {
...
for (const sp<RenderNode>& node : mRenderNodes) {
...
//递归调用各个子View对应的RenderNode执行prepareTree动作
node->prepareTree(info);
...
}
...
}
//frameworks/base/libs/hwui/RenderNode.cpp
void RenderNode::prepareTree(TreeInfo& info) {
ATRACE_CALL();
...
prepareTreeImpl(observer, info, false);
}
//frameworks/base/libs/hwui/RenderNode.cpp
void RenderNode::prepareTreeImpl(TreeObserver& observer, TreeInfo& info, bool functorsNeedLayer) {
...
//准备layer
prepareLayer(info, animatorDirtyMask);
if (info.mode == TreeInfo::MODE_FULL) {
//同步绘制命令树
pushStagingDisplayListChanges(observer, info);
}
if (mDisplayList) {
//遍历调用各个子View对应的RenderNode的prepareTreeImpl
bool isDirty = mDisplayList.prepareListAndChildren(
observer, info, childFunctorsNeedLayer,
[this](RenderNode* child, TreeObserver& observer, TreeInfo& info,
bool functorsNeedLayer) {
child->prepareTreeImpl(observer, info, functorsNeedLayer);
mHasHolePunches |= child->hasHolePunches();
});
...
} else {
...
}
//更新layer,把layer标识为正在使用的
pushLayerUpdate(info);
...
}
//frameworks/base/libs/hwui/RenderNode.cpp
void RenderNode::pushStagingDisplayListChanges(TreeObserver& observer, TreeInfo& info) {
if (mNeedsDisplayListSync) {
...
syncDisplayList(observer, &info);
...
}
}
//frameworks/base/libs/hwui/RenderNode.cpp
void RenderNode::syncDisplayList(TreeObserver& observer, TreeInfo* info) {
...
//完成赋值同步DisplayList对象
mDisplayList = std::move(mStagingDisplayList);
if (mDisplayList) {
...
mDisplayList.syncContents(syncData);
...
}
}
//frameworks/base/libs/hwui/renderthread/CanvasContext.cpp
void CanvasContext::draw(bool solelyTextureViewUpdates) {
...
{
//调用OpenGL库使用GPU,按照构建好的绘制命令完成界面的渲染
drawResult = mRenderPipeline->draw(frame, windowDirty, dirty, mLightGeometry,
&mLayerUpdateQueue, mContentDrawBounds, mOpaque,
mLightInfo, mRenderNodes, &(profiler()), mBufferParams,
profilerLock());
}
...
//等待GPU完成绘制操作
waitOnFences();
...
//将前面已经绘制渲染好的图形缓冲区Buffer上帧给SurfaceFlinger合成和显示
bool didSwap = mRenderPipeline->swapBuffers(frame, drawResult, windowDirty, mCurrentFrameInfo,
&requireSwap);
...
//标记swap buffer已经完成
mCurrentFrameInfo->markSwapBuffersCompleted();
}
Renderthread绘制过程从systrace上体现如下:
七: Surfaceflinger的合成显示
surfaceflinger负责接收来自各个应用程序的图形缓冲区(即buffer),并将他们按照特定的规则和优先级进行合成。其合成的时机类似于Choreographer,接收vsync信号来进行合成显示,Choreographer接收的是vsync-app(app类型的vsync信号),surfaceflinger接收的是vsync-sf(sf类型的vsync信号)。下面简单介绍下surfaceflinger是合入管理来自各个应用的buffer的。
surfaceflinger内部有个BufferQueue,字如其名,它就是负责管理Buffer,它的工作流程如下:
- app通过dequeueBuffer向BufferQueue申请一个可用的buffer,在拿到buffer后进行绘制,绘制完成通过queueBuffer将buffer返回到BufferQueue,并申请sf类型的vsync信号通知surfaceflinger及时进行合成
- surfaceflinger合成完成后,通过releaseBuffer将BufferQueue置为free状态,更新到BufferQueue中
以上过程在systrace中体现如下:
八:总结
应用冷启动流程到这里就完成了,优于笔者个人技术及篇幅限制,很多流程没有详细展开,后面会继续更新,出一些系列的文章来尽可能详细的展开描述。应用冷启动具体有哪些优化措施,也会考虑出专项文章。