应用冷启动详细流程分析(附源码)
1. 整体流程
1.在eventhub中,当驱动获取到触摸事件时,eventhub中通过epoll就会监听到有event可读,然后就会唤醒inputreader线程,读取事件并处理,然后inputreader会回调inputdispatcher的notifyMotion方法,将时间加入iq队列,然后通知inputdispatcher处理,inputdispatcher首先会去获取当前的焦点window, 然后将时间op队列后分发,分发完成后,将事件加入wq队列,进行事件的处理超时检测。
2.inputdeispatcher通过往目标窗口inputchannel发送数据,唤醒目标应用主线程,这里应用是launcher3, launcher3会从socket中读取对应的事件,并开始分发,其中主要还是往view树上分发,然后一直到点击事件的处理,通过startActivity启动新的应用的开始。
3.launcher3通过跨进程调用AMS启动应用的流程,首先是先pause launcher3, 因为目标应用是冷启动,需要通过socket方式通知zygote先fork出新的应用的进程,新应用进程执行自己ActivityThread的main方法,初始化自己的消息队列等,然后通过跨进程bindApplication通知AMS,将该应用加入管理记录,然后继续跨进程通知应用往下执行相应的生命周期。
4.应用执行完相应的生命周期后,开始第一帧绘制,然后显示到屏幕上,冷启动完成。
应用启动速度是用户体验的核心指标之一,无论是Google还是手机厂商还是应用开发者,都在不断地优化启动时间,为了更快一点而努力。想优化应用启动流程,就必须要对应用启动流程有充分的认识与了解。下文将会基于AndroidU的源码,结合systrace,来剖析应用冷启动的全流程。
2. 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。大致流程如下:
-
InputReader从EventHub中把Input事件读取出来,执行mQueuedListener.notify发送Input事件。
-
InputDIspatcher接收到notify回调后,更新mInboundQueue。在本身分发事件的循环中检测到mInboundQueue队列中有事件后,对事件进行分装,然后根据KeyEntry找到displayId,把事件传递到displayId对应的窗口。
-
窗口对应的app,遍历View树,处理Input事件。
这里有几个点需要注意下:
InboundQueue("iq")队列中存放着InputDispatcher从InputReader拿到的input事件。
OutboundQueue("oq")队列中存放着即将要发送给各个窗口的input事件。
WaitQueue("wq")队列中存放着已经分发给窗口app,但是app还没有处理成功的input事件。
PendingInputEventQueue("aq")队列中存放着app需要处理的input事件。
deliverInputEvent 标识着App UI线程被Input事件唤醒。
2.2 Perfetto UI中input处理流程
-
InputReader读取事件;
-
InputDispatcher接收到InputReader读取到的事件,放入InboundQueue即“iq”队列中;
-
InputDispatcher查找目标窗口,把事件放到OutboundQueue即“oq”队列中;
-
InputDispatcher把事件分发给对应窗口(也就是Launcher),把事件放入WaitQueue即“wq”队列中,等待事件处理完成。
-
Launcher接收到Input事件后,先通过enqueueInputEvent函数把事件放入到PendingInputEventQueue即“aq”队列中,并在deliverInputevent的流程中进行Input事件的分发和处理。
-
Launcher把事件先交给应用界面Window创建时的ViewRootImpl.setView流程中创建的多个不同类型的InputStage中依次进行处理,最后交给ViewPostImeInputStage进行处理,会从View布局树的根节点DecorView开始遍历View树中的每个子View或者ViewGroup进行事件的分发、拦截、处理的逻辑。
-
Input事件在View树中处理完成后会调用finishInputEvent结束应用对Input事件处理逻辑,这里会通过jni调用到native层InputConsumer的sendFinishedSignal函数通知InputDIspatcher事件处理完成,把事件从“wq”队列中移除,避免报ANR。
-
Launcher在处理一系列的ACTION_DOWN,ACTION_MOVE一直到ACTION_UP的touchu事件后,判断是点击事件,触发View的onClick函数,通过binder调用AMS的startActivity触发进程启动的流程。
3. 应用进程的创建和启动
3.1 Pause前一个应用
1.Launcher通过binder调用AMS的startActivity函数后,会执行到ActivityStarter.Request.execute函数,这里会开始记录launchingActivity的systrace tag,即perfect中看到的Android App Startups开始的地方(Perfetto中看到的进程启动开始的地方)。
//frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.javastatic class Request {...int execute() {...//systrace中统计进程启动开始的地方launchingState = mSupervisor.getActivityMetricsLogger().notifyActivityLaunching(mRequest.intent, caller, callingUid);...res = executeRequest(mRequest);...}}
2.AMS继续执行startActivity流程,在ActivityStarter.startActivityUnchecked函数中会记录startActivityInner的systrace tag,并调用startActivityInner函数,startActivityInner是真正启动Activity的地方。
//frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.javaprivate 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.在TaskFragment.resumeTopActivity函数中会调用startPausing来暂定Launcher进程。
//frameworks/base/services/core/java/com/android/server/wm/TaskFragment.javafinal boolean resumeTopActivity(ActivityRecord prev, ActivityOptions options,boolean deferPause) {...boolean pausing = !deferPause && taskDisplayArea.pauseBackTasks(next);if (mResumedActivity != null) {//开始暂停上一个Activitypausing |= 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;}
4.startPausing函数最终对通过Activity.performPause函数调用到Launcher对应Activity的onPause函数,然后调用ActivityRecord.activityPaused函数来通知taskFragment,Activity的pause已经完成,重新执行TaskFragment.resumeTopActivity函数来继续进程启动流程。回头看3,这时候pausing变量变成了true,会判断将要启动的Activity所属进程存不存在,如果没有在运行,则会调用mAtmService.startProcessAsync函数进行进程启动工作。
//frameworks/base/services/core/java/com/android/server/wm/TaskFragment.javaboolean startPausing(boolean userLeaving, boolean uiSleeping, ActivityRecord resuming,String reason) {...if (prev.attachedToProcess()) {...} else {//分发pause ActivityschedulePauseActivity(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.javafinal void performPause() {...dispatchActivityPrePaused();...//调用Launcher进程对应Activity的onPause函数onPause();...dispatchActivityPostPaused();}//frameworks/base/services/core/java/com/android/server/wm/ActivityRecord.javavoid activityPaused(boolean timeout) {...try {//通知系统Activity已经pause完成,可以继续进程启动流程taskFragment.completePause(true /* resumeNext */, null /* resumingActivity */);}...}
pause Activity的流程在Perfetto上的体现如下:
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.javaboolean startProcessLocked(...) {...try {...//进程创建成功会返回对应的pid,并保存在ProcessStartResult中final Process.ProcessStartResult startResult = startProcess(hostingRecord,entryPoint, app,uid, gids, runtimeFlags, zygotePolicyFlags, mountExternal, seInfo,requiredAbi, instructionSet, invokeWith, startUptime);//更新zygote创建进程成功后返回的pid到ProcessRecordhandleProcessStartedLocked(app, startResult.pid, startResult.usingWrapper,startSeq, false);}...}//frameworks/base/services/core/java/com/android/server/am/ProcessList.javaprivate 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 tagTrace.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.javapublic static ProcessStartResult start(...) {return ZYGOTE_PROCESS.start(...);//frameworks/base/core/java/android/os/ZygoteProcess.javaprivate Process.ProcessStartResult startViaZygote(...)throws ZygoteStartFailedEx {...synchronized(mLock) {...//把创建进程的参数通过socket发送给zygote进程,zygote进程会fork出新的进程并返回pidreturn 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创建进程成功后返回新进程的pidresult.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.javapublic static void main(String[] argv) {ZygoteServer zygoteServer = null;...Runnable caller;try {...//做fork前的一些初始化工作,主要是enable DDMSRuntimeInit.preForkInit();...if (!enableLazyPreload) {...//提前加载框架通用类和系统资源preload(bootTimingsTraceLog);...}...//初始化gcgcAndFinalize();...//创建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.javaRunnable 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.javaRunnable processCommand(ZygoteServer zygoteServer, boolean multipleOK) {try (ZygoteCommandBuffer argBuffer = new ZygoteCommandBuffer(mSocket)) {while (true) {...//调用Zygote的forkAndSpecialize函数进行fork processpid = 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.javastatic int forkAndSpecialize(...) {ZygoteHooks.preFork();//真正fork process的地方是在native层int pid = nativeForkAndSpecialize(...);...}//frameworks/base/core/java/com/android/internal/os/ZygoteConnection.javaprivate 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.2.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.javapublic static Runnable zygoteInit(int targetSdkVersion, long[] disabledCompatChanges,String[] argv, ClassLoader classLoader) {...//开始"ZygoteInit"的systrace tagTrace.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.javaprotected static Runnable applicationInit(int targetSdkVersion, long[] disabledCompatChanges,String[] argv, ClassLoader classLoader) {...//结束"ZygoteInit"的systrace tagTrace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);// Remaining arguments are passed to the start class's static mainreturn 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.javapublic static void main(String[] args) {//开始"ActivityThreadMain"的systrace tagTrace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");...//创建主线程的loop消息循环Looper.prepareMainLooper();...ActivityThread thread = new ActivityThread();//执行attach继续进行应用初始化的工作thread.attach(false, startSeq);...//结束"ActivityThreadMain"的systrace tagTrace.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();}...}}
新进程的创建在Perfetto上体现如下:
4. Applicantion的初始化及Activity的启动
4.1 Applicantion的创建及初始化
在ActivityThread.handleBindApplication初始化过程中,在应用主线程中主要完成一下工作:
-
根据AMS传入的ApplicantionInfo信息创建应用APK对应的LoadedAPK对象;
-
创建应用Applicantion的Context对象;
-
调用LoadedAPK的makeApplicationInner函数,创建应用的Applicantion对象。
//frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.javapublic 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.javaprivate 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 tagTrace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");...//在应用主线程执行handleBindApplication初始化动作handleBindApplication(data);//结束"bindApplication"的systrace tagTrace.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.javaprivate 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.javaprivate 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 创建Applicantion的Context对象
4.1.2.1 应用dex文件的加载
在创建Application的Context对象后,会尝试获取加载apk对应的资源文件,这里最终会触发ART加载应用的dex文件。
//frameworks/base/core/java/android/app/ContextImpl.javastatic 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.javapublic 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.javapublic ClassLoader getClassLoader() {synchronized (mLock) {if (mClassLoader == null) {createOrUpdateClassLoaderLocked(null /*addedPaths*/);}return mClassLoader;}}//frameworks/base/core/java/android/app/LoadedApk.javaprivate 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是nullmDefaultClassLoader = 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.javaClassLoader getClassLoaderWithSharedLibraries(...) {return getClassLoader(...);}//frameworks/base/core/java/android/app/ApplicationLoaders.javaprivate ClassLoader getClassLoader(...) {...synchronized (mLoaders) {...//创建PathClassLoader加载应用APK的Dex类,并增加相应的systrace tagTrace.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.javapublic 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.javapublic 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.javapublic Resources getResources(...) {try {//开始"ResourcesManager#getResources"的systrace tagTrace.traceBegin(Trace.TRACE_TAG_RESOURCES, "ResourcesManager#getResources");...//activityToken为getResources传入的第一个参数,此处为null,走elseif (activityToken != null) {...} else {//创建资源文件resources = createResources(key, classLoader, assetsSupplier);}return resources;} finally {//结束"ResourcesManager#getResources"的systrace tagTrace.traceEnd(Trace.TRACE_TAG_RESOURCES);}}//frameworks/base/core/java/android/app/ResourcesManager.javaprivate 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.javaprivate @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.javaprivate @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.javaprivate @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.javaprivate @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.javapublic 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.javaprivate 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函数,创建应用的Applicantion对象
//frameworks/base/core/java/android/app/LoadedApk.javaprivate Application makeApplicationInner(boolean forceDefaultAppClass,Instrumentation instrumentation, boolean allowDuplicateInstances) {...//开始"makeApplication"的systrace tagTrace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "makeApplication");...try {...//最终通过ClassLoader.loadClass创建Application对象app = mActivityThread.mInstrumentation.newApplication(cl, appClass, appContext);...} catch (Exception e) {...}...//结束"makeApplication"的systrace tagTrace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);...}
Application的创建即初始化在Perfetto上体现如下:
4.2 Activity的启动
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.javaprivate 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.javafinal 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.javaboolean attachApplication(WindowProcessController app) throws RemoteException {try {return mAttachApplicationHelper.process(app);} finally {...}}//frameworks/base/services/core/java/com/android/server/am/RootWindowContainer.javaprivate 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.javavoid 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.javavoid 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.javavoid 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.javafinal 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.javaprivate 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.javaboolean 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来startActivityresumedOnDisplay[0] |= topRunningActivity.makeActiveIfNeeded(target);}});}}//frameworks/base/services/core/java/com/android/server/wm/Task.javaprivate 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.javafinal boolean resumeTopActivity(ActivityRecord prev, ActivityOptions options,boolean deferPause) {...mTaskSupervisor.startSpecificActivity(next, true, true);...}//frameworks/base/services/core/java/com/android/server/wm/ActivityTaskSupervisor.javavoid 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.javaboolean 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.javapublic void execute(ClientTransactionHandler client, IBinder token,PendingTransactionActions pendingActions) {//开始"activityStart"的systrace tagTrace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityStart");...client.handleLaunchActivity(r, pendingActions, mDeviceId, null /* customIntent */);//结束"activityStart"的systrace tagTrace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);}//frameworks/base/core/java/android/app/ActivityThread.javapublic Activity handleLaunchActivity(ActivityClientRecord r,PendingTransactionActions pendingActions, int deviceId, Intent customIntent) {...final Activity a = performLaunchActivity(r, customIntent);...}//frameworks/base/core/java/android/app/ActivityThread.javaprivate 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 resourcesappContext.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.javafinal void attach(...) {...//创建PhoneWindow对象mWindow = new PhoneWindow(this, window, activityConfigCallback);...//为PhoneWindow设置WindowManagermWindow.setWindowManager((WindowManager)context.getSystemService(Context.WINDOW_SERVICE),mToken, mComponent.flattenToString(),(info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);...}//frameworks/base/core/java/android/app/Instrumentation.javapublic void callActivityOnCreate(Activity activity, Bundle icicle) {...activity.performCreate(icicle);...}//frameworks/base/core/java/android/app/Activity.javafinal void performCreate(Bundle icicle, PersistableBundle persistentState) {if (Trace.isTagEnabled(Trace.TRACE_TAG_WINDOW_MANAGER)) {//开始"performCreate:"的systrace tagTrace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "performCreate:"+ mComponent.getClassName());}...//恢复Activity已经申请的权限restoreHasCurrentPermissionRequest(icicle);...//调用应用的onCreate函数onCreate(icicle);...//结束"performCreate:"的systrace tagTrace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);}
4.2.2 Activity.onResume
这里主要做了两件事:
-
调用应用Activity的onResume函数。
-
执行WindowManager的addView函数开始视图绘制逻辑。
//frameworks/base/core/java/android/app/servertransaction/ResumeActivityItem.javapublic 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.javapublic 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();//获取DecorViewView 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.javapublic 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_RESUMEr.setState(ON_RESUME);...}...}//frameworks/base/core/java/android/app/Activity.javafinal void performResume(boolean followedByPause, String reason) {//开始"performResume:"的systrace tagif (Trace.isTagEnabled(Trace.TRACE_TAG_WINDOW_MANAGER)) {Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "performResume:"+ mComponent.getClassName());}...//调用Instrumentation.callActivityOnResume函数mInstrumentation.callActivityOnResume(this);...//结束"performResume:"的systrace tagTrace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);...}//frameworks/base/services/core/java/android/app/Instrumentation.javapublic void callActivityOnResume(Activity activity) {...//调用应用Activity的onResume函数activity.onResume();...}
4.2.3 Activity.onStart
Activity的启动,生命周期的执行顺序是onCreate/onStart/onReusme。
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.javaboolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,boolean andResume, boolean checkConfig) throws RemoteException {...final ClientTransaction clientTransaction = ClientTransaction.obtain(proc.getThread(), r.token);...//设置Transaction开始的Lifecycle,即ON_CREATEclientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent), ...));final ActivityLifecycleItem lifecycleItem;if (andResume) {lifecycleItem = ResumeActivityItem.obtain(isTransitionForward,r.shouldSendCompatFakeFocus());}clientTransaction.setLifecycleStateRequest(lifecycleItem);//设置Transaction结束的Lifecycle,即ON_RESUMEmService.getLifecycleManager().scheduleTransaction(clientTransaction);...}//frameworks/base/core/java/android/app/servertransaction/TransactionExecutor.javapublic void execute(ClientTransaction transaction) {...//执行回调executeCallbacks(transaction);executeLifecycleState(transaction);...}//frameworks/base/core/java/android/app/servertransaction/TransactionExecutor.javapublic 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.javaprivate void cycleToPath(ActivityClientRecord r, int finish, boolean excludeLastState,ClientTransaction transaction) {//获取Lifecycle开始的状态,这是获取到的是ON_CREATEfinal int start = r.getLifecycleState();...//获取main lifecycle states,也就是开始和结束中间的需要依次执行的transaction数组。这里传入的finish是ON_RESUMEfinal IntArray path = mHelper.getLifecyclePath(start, finish, excludeLastState);//依次执行transaction数组performLifecycleSequence(r, path, transaction);}//frameworks/base/core/java/android/app/servertransaction/TransactionExecutorHelper.javapublic 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.javaprivate 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.javapublic void handleStartActivity(ActivityClientRecord r,PendingTransactionActions pendingActions, ActivityOptions activityOptions) {...activity.performStart("handleStartActivity");r.setState(ON_START);...}//frameworks/base/core/java/android/app/Activity.javafinal void performStart(String reason) {...mInstrumentation.callActivityOnStart(this);...}//frameworks/base/core/java/android/app/Instrumentation.javapublic void callActivityOnStart(Activity activity) {//调用应用Activity的onStart函数activity.onStart();}
Activity启动流程,在Perfetto上体现如下:
5. 应用界面的绘制
在继续界面绘制的流程之前,这里先说明下一些view、window的概念、相关的基本类以及相互关系,便于理解后面流程。
View:Android应用用户界面的基本构建块,用于构建用户界面中的各种元素,如按钮、文本框、图像等。
Window:用于承载应用的用户界面。一个Activity通常对应一个Window,但也可以有多个Window,如dialog等;Window包含一个DecorView,它是View的容器,用于承载应用的内容视图
PhoneWindow:Window的实现类,负责管理应用窗口的显示、布局、交互等方面的功能;每个Activity都会有一个PhoneWindow对象来管理其所有的Window。在Activity创建过程中的attach函数中会创建一个PhoneWindow对象。
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.javapublic 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.javapublic void addView(View view, ViewGroup.LayoutParams params,Display display, Window parentWindow, int userId) {...//初始化wparamsfinal WindowManager.LayoutParams wparams = (WindowManager.LayoutParams) params;...synchronized (mLock) {...//初始化root,这里的windowlessSession是nullif (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.javapublic void setView(View view, WindowManager.LayoutParams attrs, View panelParentView,int userId) {synchronized (this) {if (mView == null) {...//触发界面绘制(onMeasure/onLayout/onDraw)requestLayout();//初始化inputChannelInputChannel 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为ViewRootImplview.assignParent(this);}}}}
5.2ViewRootImpl.requestLayout
咱们接着看requestLayout,这里会先判断更新UI的是不是主线程,只有主线程才允许更新UI。然后会通过Choreographer往主线程消息队列添加CALLBACK_TRAVERSAL绘制类型的待执行消息,最终会通过DisplayEventReceiver的scheduleVsync函数申请Vsync信号。
这里介绍下Choreographer和Vsync:
Choreographer:主要用于协调和同步 UI 绘制相关的操作。它与系统的 VSync(垂直同步)信号进行同步,确保动画的绘制和界面更新在屏幕刷新时进行,避免出现撕裂(tearing)等视觉问题。它在 Android 渲染链路中起到一个承上启下的作用。
Vsync:Vsync信号的全称是Vertical Synchronization(中文名垂直同步),由GPU厂商开发,其基本思路就是在屏幕刷新之前向外提供一个信号。例如屏幕刷新率如果是60Hz,那么每隔1000/60=16.6ms就会发送vsync信号。
承上: 负责接收和处理 App(ViewRootImpl) 的各种更新消息和回调,等到 Vsync 到来的时候统一处理。例如:集中处理Traversal(包括measure、layout、draw等操作) ,判断掉帧情况,记录 CallBack 耗时等。
启下: 负责请求和接收 Vsync 信号。
请求 Vsync:通过FrameDisplayEventReceiver.scheduleVsync()。
接收 Vsync 事件回调:通过FrameDisplayEventReceiver.onVsync()。
//frameworks/base/core/java/android/view/ViewRootImpl.javapublic void requestLayout() {if (!mHandlingLayoutInLayoutRequest) {...//检查是否是主线程。只有主线程才可以更新UIcheckThread();//触发绘制流程scheduleTraversals();}}//frameworks/base/core/java/android/view/ViewRootImpl.javavoid 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.javaprivate void postCallbackDelayedInternal(int callbackType,Object action, Object token, long delayMillis) {...synchronized (mLock) {final long now = SystemClock.uptimeMillis();//这里传入的delayMillis是0final 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.javaprivate void scheduleFrameLocked(long now) {if (!mFrameScheduled) {mFrameScheduled = true;if (USE_VSYNC) {...if (isRunningOnLooperThreadLocked()) {//请求Vsync信号scheduleVsyncLocked();}...}...}}//frameworks/base/core/java/android/view/Choreographer.javaprivate 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.javapublic 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.javaprivate Choreographer(Looper looper, int vsyncSource, long layerHandle) {mLooper = looper;//把TRACE_TAG_VIEW systrace tag和looper绑定mLooper.setTraceTag(Trace.TRACE_TAG_VIEW);//初始化FrameHandler,绑定LoopermHandler = new FrameHandler(looper);//初始化FrameDisplayEventReceiver,与SurfaceFlinger建立通信用于接收和请求Vsync信号mDisplayEventReceiver = USE_VSYNC? new FrameDisplayEventReceiver(looper, vsyncSource, layerHandle): null;mLastFrameTimeNanos = Long.MIN_VALUE;mFrameIntervalNanos = (long)(1000000000 / getRefreshRate());//初始化CallbackQueue,数组长度为5mCallbackQueues = new CallbackQueue[CALLBACK_LAST + 1];for (int i = 0; i <= CALLBACK_LAST; i++) {mCallbackQueues[i] = new CallbackQueue();}...}//frameworks/base/core/java/android/view/Choreographer.javaprivate final class FrameDisplayEventReceiver extends DisplayEventReceiverimplements 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);}}@Overridepublic void run() {//调用主处理函数doFramedoFrame(mTimestampNanos, mFrame, mLastVsyncEventData);}}//frameworks/base/core/java/android/view/Choreographer.javavoid 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类型的callbackdoCallbacks(Choreographer.CALLBACK_INPUT, frameIntervalNanos);//处理insets animation类型的callbackdoCallbacks(Choreographer.CALLBACK_INSETS_ANIMATION, frameIntervalNanos);//处理traversal类型的callback,这里会回调到ViewRootImpl,触发view的绘制逻辑doCallbacks(Choreographer.CALLBACK_TRAVERSAL, frameIntervalNanos);//处理commit类型的callbackdoCallbacks(Choreographer.CALLBACK_COMMIT, frameIntervalNanos);}}//frameworks/base/core/java/android/view/ViewRootImpl.javafinal class TraversalRunnable implements Runnable {@Overridepublic void run() {doTraversal();}}//frameworks/base/core/java/android/view/ViewRootImpl.javavoid doTraversal() {if (mTraversalScheduled) {...//调用removeSyncBarrier及时移除主线程MessageQueue中的Barrier同步栅栏,以避免主线程发生"假死"mHandler.getLooper().getQueue().removeSyncBarrier(mTraversalBarrier);...performTraversals();...}}//frameworks/base/core/java/android/view/ViewRootImpl.javaprivate 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.javaprivate void performMeasure(int childWidthMeasureSpec, int childHeightMeasureSpec) {//开始记录measure的systrace tagTrace.traceBegin(Trace.TRACE_TAG_VIEW, "measure");try {//完成以DecorView为根节点的整个View树的measure工作,View绘制三部曲的第一步measuremView.measure(childWidthMeasureSpec, childHeightMeasureSpec);} finally {//结束记录measure的systrace tagTrace.traceEnd(Trace.TRACE_TAG_VIEW);}...}//frameworks/base/core/java/android/view/ViewRootImpl.javaprivate void performLayout(WindowManager.LayoutParams lp, int desiredWindowWidth,int desiredWindowHeight) {...//开始记录layout的systrace tagTrace.traceBegin(Trace.TRACE_TAG_VIEW, "layout");try {//完成以DecorView为根节点的整个View树的layout工作,View绘制三部曲的第二步layouthost.layout(0, 0, host.getMeasuredWidth(), host.getMeasuredHeight());...} finally {//结束记录layout的systrace tagTrace.traceEnd(Trace.TRACE_TAG_VIEW);}...}//frameworks/base/core/java/android/view/ViewRootImpl.javaprivate boolean performDraw() {...//开始记录draw的systrace tagTrace.traceBegin(Trace.TRACE_TAG_VIEW, "draw");...try {boolean canUseAsync = draw(fullRedrawNeeded, usingAsyncReport && mSyncBuffer);...} finally {//结束记录draw的systrace tagTrace.traceEnd(Trace.TRACE_TAG_VIEW);}...}//frameworks/base/core/java/android/view/ViewRootImpl.javaprivate boolean draw(boolean fullRedrawNeeded, boolean forceDraw) {...//如果开启了硬绘if (isHardwareEnabled()) {...//在Renderthread中做绘制动作(现在绝大部分走硬绘)mAttachInfo.mThreadedRenderer.draw(mView, mAttachInfo, this);...} else {...//走软绘流程if (!drawSoftware(...)) {...}}...}
以上过程其实就是view绘制三部曲,在Perfetto上体现如下:
6. ReaderThread的绘制
目前Android 4.X之后系统默认是开启硬件加速的,所以我们重点分析硬件加速条件下的界面渲染流程。
-
从DecorView根节点出发,递归遍历View控件树,记录每个View节点的绘制操作命令,完成绘制操作命令树的构建。
-
JNI调用同步Java层构建的绘制命令树到Native层的RenderThread渲染线程,并唤醒渲染线程利用OpenGL执行渲染任务。
//frameworks/base/core/java/android/view/ThreadedRenderer.javavoid 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.javaprivate void updateRootDisplayList(View view, DrawCallbacks callbacks) {//开始记录"Record View#draw()"的systrace tagTrace.traceBegin(Trace.TRACE_TAG_VIEW, "Record View#draw()");//递归子View的updateDisplayListIfDirty实现构建DisplayListOpupdateViewTreeDisplayList(view);...if (mRootNodeNeedsUpdate || !mRootNode.hasDisplayList()) {//获取根View的SkiaRecordingCanvasRecordingCanvas canvas = mRootNode.beginRecording(mSurfaceWidth, mSurfaceHeight);try {...//利用canvas缓存DisplayListOp绘制命令canvas.drawRenderNode(view.updateDisplayListIfDirty());...} finally {//将所有DisplayListOp绘制命令填充到RootRenderNode中mRootNode.endRecording();}}...//结束记录"Record View#draw()"的systrace tagTrace.traceEnd(Trace.TRACE_TAG_VIEW);}//frameworks/base/core/java/android/view/ThreadedRenderer.javaprivate void updateViewTreeDisplayList(View view) {...//从DecorView根节点出发,开始递归调用每个View树节点的updateDisplayListIfDirty函数view.updateDisplayListIfDirty();...}//frameworks/base/core/java/android/view/View.javapublic RenderNode updateDisplayListIfDirty() {final RenderNode renderNode = mRenderNode;...if ((mPrivateFlags & PFLAG_DRAWING_CACHE_VALID) == 0|| !renderNode.hasDisplayList()|| (mRecreateDisplayList)) {//如果已经有了DisplayList且不需要重新创建DisplayListif (renderNode.hasDisplayList()&& !mRecreateDisplayList) {...//获取view的DisplayList,DisplayList是一个存储了view绘制所需的绘制命令和属性的数据结构。dispatchGetDisplayList();...return renderNode; // no work needed}...//if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {//开始记录"HWUI:"的systrace tagTrace.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,并且自身不用绘制,直接递归子ViewdispatchDraw(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 tagTrace.traceEnd(Trace.TRACE_TAG_VIEW);}}...}//frameworks/base/graphics/java/android/graphics/RenderNode.javapublic @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.javapublic void draw(@NonNull Canvas canvas) {...//draw content viewonDraw(canvas);...//触发子view的draw操作dispatchDraw(canvas);...}//frameworks/base/graphics/java/android/graphics/RenderNode.javapublic 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.javapublic 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 tagATRACE_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) {...//准备layerprepareLayer(info, animatorDirtyMask);if (info.mode == TreeInfo::MODE_FULL) {//同步绘制命令树pushStagingDisplayListChanges(observer, info);}if (mDisplayList) {//遍历调用各个子View对应的RenderNode的prepareTreeImplbool 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绘制过程从Perfetto上体现如下:
7. 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中。
以上过程在Perfetto中体现如下: