日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

c++builder启动了怎么停止_App 竟然是这样跑起来的 —— Android App/Activity 启动流程分析...

發(fā)布時間:2024/1/23 c/c++ 79 豆豆
生活随笔 收集整理的這篇文章主要介紹了 c++builder启动了怎么停止_App 竟然是这样跑起来的 —— Android App/Activity 启动流程分析... 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

在我的上一篇文章:

AJie:按下電源鍵后竟然發(fā)生了這一幕 —— Android 系統(tǒng)啟動流程分析?zhuanlan.zhihu.com

我們分析了系統(tǒng)在開機以后的一系列行為,其中最后一階段 AMS(ActivityManagerService) 會啟動 Launcher 來展示我們手機中所有已安裝的應(yīng)用圖標(biāo),點擊圖標(biāo)后相應(yīng)的應(yīng)用程序?qū)幌到y(tǒng)啟動運行并展示在我們面前,那么,點擊了圖標(biāo)之后系統(tǒng)道理做了哪些工作呢?應(yīng)用進程是怎么被啟動的呢?Activity 的生命周期是什么時候被誰調(diào)用的呢?本文將繼續(xù)基于 Android Nougat 的 frameworks 層源碼的解答這些問題。

閱讀建議: 如果你是首次閱讀這個過程的源碼,建議你忽略一些細(xì)枝末節(jié)的代碼,先抓主干代碼,從整體上理解代碼的執(zhí)行流程(右下角文章目錄視圖中可以點擊跳轉(zhuǎn)到相應(yīng)章節(jié)),否則將會被細(xì)節(jié)的代碼擾亂思路。最后可以回頭多看幾遍,這時候如果有需要可以追蹤一些枝干代碼,做到融會貫通。

1. Launcher —— AMS

1.1 調(diào)用過程分析

1.1.1 Launcher.onClick

在 Launcher app 的主 Activity —— Launcher.java 中,App 圖標(biāo)的點擊事件最終會回調(diào) Launcher.java 中的 onClick 方法,

packages/apps/Launcher3/src/com/android/launcher3/Launcher.java:

public void onClick(View v) {...Object tag = v.getTag();if (tag instanceof ShortcutInfo) {// 從快捷方式圖標(biāo)啟動onClickAppShortcut(v);} else if (tag instanceof FolderInfo) {// 文件夾if (v instanceof FolderIcon) {onClickFolderIcon(v);}} else if (v == mAllAppsButton) {// “所有應(yīng)用”按鈕onClickAllAppsButton(v);} else if (tag instanceof AppInfo) {// 從“所有應(yīng)用”中啟動的應(yīng)用startAppShortcutOrInfoActivity(v);} else if (tag instanceof LauncherAppWidgetInfo) {// 組件if (v instanceof PendingAppWidgetHostView) {onClickPendingWidget((PendingAppWidgetHostView) v);}} }

1.1.2 Launcher.onClickAppShortcut

如果是快捷方式圖標(biāo),則調(diào)用 onClickAppShortcut 方法進而調(diào)用 startAppShortcutOrInfoActivity 方法:

@Thunk void startAppShortcutOrInfoActivity(View v) {Object tag = v.getTag();final ShortcutInfo shortcut;final Intent intent;if (tag instanceof ShortcutInfo) {shortcut = (ShortcutInfo) tag;// 去除對應(yīng)的 Intent 對象intent = shortcut.intent;int[] pos = new int[2];v.getLocationOnScreen(pos);intent.setSourceBounds(new Rect(pos[0], pos[1],pos[0] + v.getWidth(), pos[1] + v.getHeight()));} else if (tag instanceof AppInfo) {shortcut = null;intent = ((AppInfo) tag).intent;} else {throw new IllegalArgumentException("Input must be a Shortcut or AppInfo");}// 調(diào)用 startActivitySafely 方法boolean success = startActivitySafely(v, intent, tag);mStats.recordLaunch(v, intent, shortcut);if (success && v instanceof BubbleTextView) {mWaitingForResume = (BubbleTextView) v;mWaitingForResume.setStayPressed(true);} }

1.1.3 Launcher.startActivity

獲取相應(yīng) App 的 Intent 信息之后,調(diào)用 startActivity 方法:

private boolean startActivity(View v, Intent intent, Object tag) {// 啟動新的任務(wù)棧intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);try {...if (user == null || user.equals(UserHandleCompat.myUserHandle())) {StrictMode.VmPolicy oldPolicy = StrictMode.getVmPolicy();try { StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder().detectAll().penaltyLog().build());// 調(diào)用 Activity 的 startActivity 方法startActivity(intent, optsBundle);} finally {StrictMode.setVmPolicy(oldPolicy);}} else {launcherApps.startActivityForProfile(intent.getComponent(), user,intent.getSourceBounds(), optsBundle);}return true;} catch (SecurityException e) { ...}return false; }

1.1.4 Activity.startActivity

這里最終調(diào)用了 Activity 中的 startActivity 方法,并且設(shè)置 Flag 為 FLAG_ACTIVITY_NEW_TASK。到此為止,已經(jīng)跟啟動普通的 Activity 流程匯合起來了,繼續(xù)往下分析。

frameworks/base/core/java/android/app/Activity.java:

@Override public void startActivity(Intent intent, @Nullable Bundle options) {// 第二個參數(shù)為 -1 表示不需要回調(diào) onActivityResult 方法if (options != null) {startActivityForResult(intent, -1, options);} else {// Note we want to go through this call for compatibility with// applications that may have overridden the method.startActivityForResult(intent, -1);} }

1.1.5 Activity.startActivityForResult

調(diào)用 Activity 的 startActivityForResult 方法

public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,@Nullable Bundle options) {// mParent 是當(dāng)前 Activity 的父類,此時條件成立if (mParent == null) {// 調(diào)用 Instrumentation 的 execStartActivity 方法Instrumentation.ActivityResult ar = mInstrumentation.execStartActivity(this,mMainThread.getApplicationThread(), mToken, this, intent, requestCode, options);...} else {...} }

1.1.6 Instrumentation.execStartActivity

frameworks/base/core/java/android/app/Instrumentation.java:

public ActivityResult execStartActivity(Context who, IBinder contextThread, IBinder token, Activity target,Intent intent, int requestCode, Bundle options) {...try {intent.migrateExtraStreamToClipData();intent.prepareToLeaveProcess(who);// 獲取 AMS 的代理對象并調(diào)用其 startActivity 方法int result = ActivityManagerNative.getDefault().startActivity(whoThread, who.getBasePackageName(), intent,intent.resolveTypeIfNeeded(who.getContentResolver()),token, target != null ? target.mEmbeddedID : null,requestCode, 0, null, options);checkStartActivityResult(result, intent);} catch (RemoteException e) {throw new RuntimeException("Failure from system", e);}return null; }

1.1.7 ActivityManagerProxy.startActivity

以上過程是在 Launcher App 所在的進程中發(fā)生的,在我的另外一篇文章

AJie:借助 AIDL 理解 Android Binder 機制——AIDL 的使用和原理分析?zhuanlan.zhihu.com

中我們分析了 AIDL 的實現(xiàn)過程,由于遠(yuǎn)程 Service 跟使用 Service 的 Activity 不在同一個進程中,因此他們之間交互需要通過 Binder IPC 機制的支持,在這個過程中Client 首先獲取到 Server 端的代理對象,在 Client 看來 Server 代理對象同樣具有 Server 本地對象承諾的能力,因此 Client 可以調(diào)用 Server 代理對象跟 Sever 本地對象進行數(shù)據(jù)交互,Binder 驅(qū)動作為橋梁在他們中間起到中間人的作用。

在Android 系統(tǒng)啟動流程分析中曾經(jīng)分析過,AMS 是運行在 system_server 線程中的,這時 AMS 就相當(dāng)于 AIDL 中的遠(yuǎn)程 Service,App 進程要與 AMS 交互,需要通過 AMS 的代理對象 AMP(ActivityManagerProxy) 來完成,來看 ActivityManagerNative.getDefault() 拿到的是什么:

frameworks/base/core/java/android/app/ActivityManagerNative.java:

static public IActivityManager getDefault() {return gDefault.get(); }

getDefault 是一個靜態(tài)變量:

private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {protected IActivityManager create() {// 向 ServiceManager 查詢一個 key 為 "activity" 的引用IBinder b = ServiceManager.getService("activity");if (false) {Log.v("ActivityManager", "default service binder = " + b);}IActivityManager am = asInterface(b);if (false) {Log.v("ActivityManager", "default service = " + am);}return am;} };

同樣,在文章

AJie:借助 AIDL 理解 Android Binder 機制——Binder 來龍去脈?zhuanlan.zhihu.com

中也講到過:

ServiceManager 是 Binder IPC 通信過程的核心,是上下文的管理者,Binder 服務(wù)端必須先向 ServerManager 注冊才能夠為客戶端提供服務(wù),Binder 客戶端在與服務(wù)端通信之前需要從 ServerManager 中查找并獲取 Binder 服務(wù)端的引用。

這里通過 "activity" 這個名字向 ServiceManager 查詢 AMS 的引用,獲取 AMS 的引用后,調(diào)用 asInterface 方法:

static public IActivityManager asInterface(IBinder obj) {if (obj == null) {return null;}// 根據(jù) descriptor 查詢 obj 是否為 Binder 本地對象,具體過程請看前文中提到的文章IActivityManager in = (IActivityManager)obj.queryLocalInterface(descriptor);if (in != null) {return in;}// 如果 obj 不是 Binder 本地對象,則將其包裝成代理對象并返回return new ActivityManagerProxy(obj); }

因為 AMS 與 Launcher App 不在同一個進程中,這里返回的 IBinder 對象是一個 Binder 代理對象,因此這類將其包裝成 AMP(ActivityManagerProxy) 對象并返回,AMP 是 AMN(ActivityManagerNative) 的內(nèi)部類,查看 AMP 類 :

class ActivityManagerProxy implements IActivityManager {public ActivityManagerProxy(IBinder remote){mRemote = remote;}public IBinder asBinder(){return mRemote;}public int startActivity(IApplicationThread caller, String callingPackage, Intent intent,String resolvedType, IBinder resultTo, String resultWho, int requestCode,int startFlags, ProfilerInfo profilerInfo, Bundle options) throws RemoteException {...// 調(diào)用號為 START_ACTIVITY_TRANSACTIONmRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0);reply.readException();int result = reply.readInt();reply.recycle();data.recycle();return result;}...public ComponentName startService(IApplicationThread caller, Intent service,String resolvedType, String callingPackage, int userId) throws RemoteException{...mRemote.transact(START_SERVICE_TRANSACTION, data, reply, 0);reply.readException();ComponentName res = ComponentName.readFromParcel(reply);data.recycle();reply.recycle();return res;}... }

可以看到,AMP 里面將客戶端的請求通過 mRemote.transact 進行轉(zhuǎn)發(fā),mRemote 對象正是 Binder 驅(qū)動返回來的 Binder Proxy 對象,通過 Binder Proxy,Binder 驅(qū)動最終將調(diào)用處于 Binder Server 端 AMN 中的 onTransact 方法:

@Override public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {// 根據(jù)方法調(diào)用號 code 決定調(diào)用哪個方法switch (code) {case START_ACTIVITY_TRANSACTION:{...// 調(diào)用 startActivity 方法int result = startActivity(app, callingPackage, intent, resolvedType,resultTo, resultWho, requestCode, startFlags, profilerInfo, options);reply.writeNoException();reply.writeInt(result);return true;}...case START_SERVICE_TRANSACTION: {...ComponentName cn = startService(app, service, resolvedType, callingPackage, userId);reply.writeNoException();ComponentName.writeToParcel(cn, reply);return true;}...} }

1.1.8 ActivityManagerService.startActivity

AMN 是一個抽象類,它的 startActivity 為抽象方法,具體的實現(xiàn)在 frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java 中:

@Override public final int startActivity(IApplicationThread caller, String callingPackage,Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,resultWho, requestCode, startFlags, profilerInfo, bOptions,UserHandle.getCallingUserId()); }

1.2 小結(jié)

從 Launcher App 到 AMS 的調(diào)用過程中使用了 Binder IPC 機制,如果你已經(jīng)看了上面提到的我之前寫的兩篇文章——借助 AIDL 理解 Android Binder 機制——Binder 來龍去脈和借助 AIDL 理解 Android Binder 機制——AIDL 的使用和原理分析,并且運行了文章中使用到的 Demo,你應(yīng)該可以發(fā)現(xiàn),相對于 AIDL 的調(diào)用過程,調(diào)用方 Launcher App 相當(dāng)于 AIDL 過程中的 Activity 所在的 App,充當(dāng) Clinent 的角色;AMS 相當(dāng)于遠(yuǎn)程 Service 的角色,充當(dāng) Server 端角色,他們的調(diào)用過程總體上都是一樣的。

從 Launcher App 到 AMS 的時序圖如下:

2. AMS —— zygote

2.1 調(diào)用過程分析

2.1.1 ActivityManagerService.startActivityAsUser

接著從 AMS 的 startActivityAsUser 方法開始分析:

@Override public final int startActivityAsUser(IApplicationThread caller, String callingPackage,Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {enforceNotIsolatedCaller("startActivity");userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),userId, false, ALLOW_FULL_ONLY, "startActivity", null);// TODO: Switch to user app stacks here.// 調(diào)用 ActivityStarter 的 startActivityMayWait 方法return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,profilerInfo, null, null, bOptions, false, userId, null, null); }

2.1.2 ActivityStarter.startActivityMayWait

繼續(xù)跟進 frameworks/base/services/core/java/com/android/server/am/ActivityStarter.java:

final int startActivityMayWait(IApplicationThread caller, int callingUid,String callingPackage, Intent intent, String resolvedType,IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,IBinder resultTo, String resultWho, int requestCode, int startFlags,ProfilerInfo profilerInfo, IActivityManager.WaitResult outResult, Configuration config,Bundle bOptions, boolean ignoreTargetSecurity, int userId,IActivityContainer iContainer, TaskRecord inTask) {...synchronized (mService) {...// 調(diào)用 startActivityLocked 方法int res = startActivityLocked(caller, intent, ephemeralIntent, resolvedType,aInfo, rInfo, voiceSession, voiceInteractor,resultTo, resultWho, requestCode, callingPid,callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,options, ignoreTargetSecurity, componentSpecified, outRecord, container,inTask);...return res;} }

2.1.3 ActivityStarter.startActivityLocked

查看 startActivityLocked 方法:

final int startActivityLocked(IApplicationThread caller, Intent intent, Intent ephemeralIntent,String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,String callingPackage, int realCallingPid, int realCallingUid, int startFlags,ActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,ActivityRecord[] outActivity, ActivityStackSupervisor.ActivityContainer container,TaskRecord inTask) {...// 調(diào)用 doPendingActivityLaunchesLocked 方法,傳入 false 參數(shù)doPendingActivityLaunchesLocked(false);...return err; }

2.1.4 ActivityStarter.doPendingActivityLaunchesLocked

查看 doPendingActivityLaunchesLocked 方法:

final void doPendingActivityLaunchesLocked(boolean doResume) {while (!mPendingActivityLaunches.isEmpty()) {final PendingActivityLaunch pal = mPendingActivityLaunches.remove(0);final boolean resume = doResume && mPendingActivityLaunches.isEmpty();try {// 調(diào)用 startActivityUnchecked 方法final int result = startActivityUnchecked(pal.r, pal.sourceRecord, null, null,pal.startFlags, resume, null, null);postStartActivityUncheckedProcessing(pal.r, result, mSupervisor.mFocusedStack.mStackId, mSourceRecord, mTargetStack);} catch (Exception e) {Slog.e(TAG, "Exception during pending activity launch pal=" + pal, e);pal.sendErrorResult(e.getMessage());}} }

2.1.5 ActivityStarter.startActivityUnchecked

查看 startActivityUnchecked 方法:

private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask) {... // 調(diào)用 ActivityStackSupervisor 的 resumeFocusedStackTopActivityLocked 方法mSupervisor.resumeFocusedStackTopActivityLocked(); ... return START_SUCCESS; }

2.1.6 ActivityStackSupervisor.resumeFocusedStackTopActivityLocked

frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java:

boolean resumeFocusedStackTopActivityLocked(ActivityStack targetStack, ActivityRecord target,ActivityOptions targetOptions) {if (targetStack != null && isFocusedStack(targetStack)) {return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);}final ActivityRecord r = mFocusedStack.topRunningActivityLocked();if (r == null || r.state != RESUMED) {// 調(diào)用 ActivityStack 的 resumeTopActivityUncheckedLocked 方法mFocusedStack.resumeTopActivityUncheckedLocked(null, null);}return false; }

2.1.7 ActivityStack.resumeTopActivityUncheckedLocked

查看 ActivityStack 的 resumeTopActivityUncheckedLocked 方法:

boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {...try {...// 調(diào)用 resumeTopActivityInnerLocked 方法result = resumeTopActivityInnerLocked(prev, options);} finally {mStackSupervisor.inResumeTopActivity = false;}return result; }

2.1.8 ActivityStack.resumeTopActivityInnerLocked

查看 resumeTopActivityInnerLocked 方法:

private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {...final ActivityRecord next = topRunningActivityLocked();...if (next.app != null && next.app.thread != null) {...} else {...if (DEBUG_STATES) Slog.d(TAG_STATES, "resumeTopActivityLocked: Restarting " + next);// 調(diào)用 ActivityStackSupervisor 的 startSpecificActivityLocked 方法mStackSupervisor.startSpecificActivityLocked(next, true, true);}if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();return true; }

2.1.9 ActivityStackSupervisor.startSpecificActivityLocked

回到 ActivityStackSupervisor 的 startSpecificActivityLocked 方法:

void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) {// 當(dāng)前 Activity 附屬的 ApplicationProcessRecord app = mService.getProcessRecordLocked(r.processName,r.info.applicationInfo.uid, true);r.task.stack.setLaunchTime(r);// 如果 Application 已經(jīng)運行if (app != null && app.thread != null) {try {if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0|| !"android".equals(r.info.packageName)) {app.addPackage(r.info.packageName, r.info.applicationInfo.versionCode,mService.mProcessStats);}realStartActivityLocked(r, app, andResume, checkConfig);return;} catch (RemoteException e) {Slog.w(TAG, "Exception when starting activity "+ r.intent.getComponent().flattenToShortString(), e);}}// 啟動新進程mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,"activity", r.intent.getComponent(), false, false, true); }

首先,在方法中獲取了當(dāng)前 Activity 附屬的 Application,如果已經(jīng)在運行了,說明這個 App 是已經(jīng)被啟動過了的,這時候調(diào)用 realStartActivityLocked 方法就可以進入下一步的流程了,同一個 App 中不同 Activity 的相互啟動就是走的這個流程。當(dāng) Application 沒有運行的時候,就需要調(diào)用 AMS 的 startProcessLocked 方法啟動一個進程去承載它然后完成后續(xù)的工作,順便鋪墊一下,當(dāng)新進程被啟動完成后還會調(diào)用回到這個方法,查看 AMS 的 startProcessLocked 方法:

2.1.10 ActivityManagerService.startProcessLocked

final ProcessRecord startProcessLocked(String processName,ApplicationInfo info, boolean knownToBeDead, int intentFlags,String hostingType, ComponentName hostingName, boolean allowWhileBooting,boolean isolated, boolean keepIfLarge) {return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,null /* crashHandler */); }

2.1.11 ActivityManagerService.startProcessLocked

調(diào)用 startProcessLocked 方法:

final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler){...startProcessLocked(app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);checkTime(startTime, "startProcess: done starting proc!");return (app.pid != 0) ? app : null; }

2.1.12 ActivityManagerService.startProcessLocked

調(diào)用 startProcessLocked 的重載方法:

private final void startProcessLocked(ProcessRecord app, String hostingType,String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs){...try {...// 調(diào)用 Process 的 start 方法Process.ProcessStartResult startResult = Process.start(entryPoint,app.processName, uid, uid, gids, debugFlags, mountExternal,app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,app.info.dataDir, entryPointArgs);...} catch (RuntimeException e) {...} }

2.1.13 Process.start

frameworks/base/services/core/java/android/os/Process.java:

public static final ProcessStartResult start(final String processClass,final String niceName,int uid, int gid, int[] gids,int debugFlags, int mountExternal,int targetSdkVersion,String seInfo,String abi,String instructionSet,String appDataDir,String[] zygoteArgs) {try {// 調(diào)用 startViaZygote 方法return startViaZygote(processClass, niceName, uid, gid, gids,debugFlags, mountExternal, targetSdkVersion, seInfo,abi, instructionSet, appDataDir, zygoteArgs);} catch (ZygoteStartFailedEx ex) {Log.e(LOG_TAG,"Starting VM process through Zygote failed");throw new RuntimeException("Starting VM process through Zygote failed", ex);} }

2.1.14 Process.startViaZygote

查看 startViaZygote 方法:

private static ProcessStartResult startViaZygote(final String processClass,final String niceName,final int uid, final int gid,final int[] gids,int debugFlags, int mountExternal,int targetSdkVersion,String seInfo,String abi,String instructionSet,String appDataDir,String[] extraArgs)throws ZygoteStartFailedEx {synchronized(Process.class) {...// 調(diào)用 zygoteSendArgsAndGetResult 方法,傳入 openZygoteSocketIfNeeded 的返回值return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote);} }

2.1.15 Process.zygoteSendArgsAndGetResult、Process.openZygoteSocketIfNeeded

查看 zygoteSendArgsAndGetResult 方法:

private static ProcessStartResult zygoteSendArgsAndGetResult(ZygoteState zygoteState, ArrayList<String> args)throws ZygoteStartFailedEx {try {...final BufferedWriter writer = zygoteState.writer;final DataInputStream inputStream = zygoteState.inputStream;writer.write(Integer.toString(args.size()));writer.newLine();for (int i = 0; i < sz; i++) {String arg = args.get(i);writer.write(arg);writer.newLine();}writer.flush();// Should there be a timeout on this?ProcessStartResult result = new ProcessStartResult();// 等待 socket 服務(wù)端(即zygote)返回新創(chuàng)建的進程pid;result.pid = inputStream.readInt();result.usingWrapper = inputStream.readBoolean();if (result.pid < 0) {throw new ZygoteStartFailedEx("fork() failed");}return result;} catch (IOException ex) {zygoteState.close();throw new ZygoteStartFailedEx(ex);} }

在 zygoteSendArgsAndGetResult 中等待 Socket 服務(wù)端,也就是 zygote 進程返回創(chuàng)建新進程的結(jié)果,這里 zygoteState 參數(shù)是由 openZygoteSocketIfNeeded 方法返回的,openZygoteSocketIfNeeded 方法則負(fù)責(zé)根據(jù) abi 向 Zygote 進程發(fā)起連接請求:

private static ZygoteState openZygoteSocketIfNeeded(String abi) throws ZygoteStartFailedEx {if (primaryZygoteState == null || primaryZygoteState.isClosed()) {try {// 向主zygote發(fā)起connect()操作primaryZygoteState = ZygoteState.connect(ZYGOTE_SOCKET);} catch (IOException ioe) {throw new ZygoteStartFailedEx("Error connecting to primary zygote", ioe);}}if (primaryZygoteState.matches(abi)) {return primaryZygoteState;}if (secondaryZygoteState == null || secondaryZygoteState.isClosed()) {try {// 當(dāng)主zygote沒能匹配成功,則采用第二個zygote,發(fā)起connect()操作secondaryZygoteState = ZygoteState.connect(SECONDARY_ZYGOTE_SOCKET);} catch (IOException ioe) {throw new ZygoteStartFailedEx("Error connecting to secondary zygote", ioe);}}if (secondaryZygoteState.matches(abi)) {return secondaryZygoteState;}throw new ZygoteStartFailedEx("Unsupported zygote ABI: " + abi); }

2.2 小結(jié)

如果是從桌面新啟動一個 App 中的 Activity,此時是沒有進程去承載這個 App 的,因此需要通過 AMS 向 zygote 繼承發(fā)起請求去完成這個任務(wù),AMS 運行在 system_server 進程中,它通過 Socket 向 zygote 發(fā)起 fock 進程的請求,從 AMS 開始的調(diào)用時序圖如下:

3. zygote —— ActivityThread

3.1 調(diào)用過程分析

3.1.1 ZygoteInit.main

在 Android 系統(tǒng)啟動流程分析 文中提到過 zygote 進程的其中一項任務(wù)就是:

調(diào)用 registerZygoteSocket() 函數(shù)建立 Socket 通道,使 zygote 進程成為 Socket 服務(wù)端,并通過 runSelectLoop() 函數(shù)等待 ActivityManagerService 發(fā)送請求創(chuàng)建新的應(yīng)用程序進程。

zygote 終于要再次上場了!接下來從 ZygoteInit.java 的 main 方法開始回顧一下 zygote 進程的工作:

frameworks/base/core/java/com/android/internal/os/ZygoteInit.java:

public static void main(String argv[]) {try {...runSelectLoop(abiList);....} catch (MethodAndArgsCaller caller) {caller.run();} catch (RuntimeException ex) {closeServerSocket();throw ex;} }

3.1.2 ZygoteInit.runSelectLoop

查看 runSelectLoop 方法:

private static void runSelectLoop(String abiList) throws MethodAndArgsCaller {...// 循環(huán)讀取狀態(tài)while (true) {...for (int i = pollFds.length - 1; i >= 0; --i) {// 讀取的狀態(tài)不是客戶端連接或者數(shù)據(jù)請求時,進入下一次循環(huán)if ((pollFds[i].revents & POLLIN) == 0) {continue;}if (i == 0) {// i = 0 表示跟客戶端 Socket 連接上了ZygoteConnection newPeer = acceptCommandPeer(abiList);peers.add(newPeer);fds.add(newPeer.getFileDesciptor());} else {// i > 0 表示接收到客戶端 Socket 發(fā)送過來的請求// runOnce 方法創(chuàng)建一個新的應(yīng)用程序進程boolean done = peers.get(i).runOnce();if (done) {peers.remove(i);fds.remove(i);}}}} }

3.1.3 ZygoteConnection.runOnce

查看 frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java 的 runOnce 方法:

boolean runOnce() throws ZygoteInit.MethodAndArgsCaller {String args[];Arguments parsedArgs = null;FileDescriptor[] descriptors;try {// 讀取 socket 客戶端發(fā)送過來的參數(shù)列表args = readArgumentList();descriptors = mSocket.getAncillaryFileDescriptors();} catch (IOException ex) {// EOF reached.closeSocket();return true;}...try {// 將 socket 客戶端傳遞過來的參數(shù),解析成 Arguments 對象格式parsedArgs = new Arguments(args);...// 同樣調(diào)用 Zygote.java 的 forkAndSpecialize 方法 fock 出子進程pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids,parsedArgs.debugFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo,parsedArgs.niceName, fdsToClose, parsedArgs.instructionSet,parsedArgs.appDataDir);} catch (Exception e) {...}try {if (pid == 0) {// 子進程執(zhí)行IoUtils.closeQuietly(serverPipeFd);serverPipeFd = null;// 進入子進程流程handleChildProc(parsedArgs, descriptors, childPipeFd, newStderr);return true;} else {// 父進程執(zhí)行IoUtils.closeQuietly(childPipeFd);childPipeFd = null;return handleParentProc(pid, descriptors, serverPipeFd, parsedArgs);}} finally {IoUtils.closeQuietly(childPipeFd);IoUtils.closeQuietly(serverPipeFd);} }

3.1.4 ZygoteConnection.handleChildProc

首先解析 Socket 客戶端傳過來的參數(shù),Zygote.java 的 forkAndSpecialize 返回的 pid == 0 的時候表示此時在 fock 出來的子進程中執(zhí)行,繼續(xù)調(diào)用 handleChildProc 方法,并將參數(shù)繼續(xù)層層傳遞:

private void handleChildProc(Arguments parsedArgs, FileDescriptor[] descriptors, FileDescriptor pipeFd, PrintStream newStderr) throws ZygoteInit.MethodAndArgsCaller {/*由于 fock 出來的 system_server 進程會復(fù)制 zygote 進程的地址空間,因此它也得到了 zygote進程中的 Socket,這個 Socket 對它來說并無用處,這里將其關(guān)閉 */closeSocket();ZygoteInit.closeServerSocket();...if (parsedArgs.niceName != null) {// 設(shè)置進程名Process.setArgV0(parsedArgs.niceName);}if (parsedArgs.invokeWith != null) {...} else {// 調(diào)用 RuntimeInit 的 zygoteInit 方法RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion,parsedArgs.remainingArgs, null);} }

3.1.5 RuntimeInit.zygoteInit

查看 frameworks/base/core/java/com/android/internal/os/RuntimeInit.java 的 zygoteInit 方法:

public static final void zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) throws ZygoteInit.MethodAndArgsCaller {if (DEBUG) Slog.d(TAG, "RuntimeInit: Starting application from zygote");Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "RuntimeInit");// 重定向 log 輸出redirectLogStreams();// 初始化一些通用的設(shè)置commonInit(); /***通過 Native 層中 AndroidRuntime.cpp 的 JNI 方法最終調(diào)用 app_main.cpp 的 *onZygoteInit 方法啟動 Binder 線程池, 使 system_server 進程可以使用 Binder *與其他進程通信**/nativeZygoteInit(); applicationInit(targetSdkVersion, argv, classLoader); }

3.1.6 RuntimeInit.applicationInit

繼續(xù)調(diào)用 applicationInit 方法:

private static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)throws ZygoteInit.MethodAndArgsCaller {...// 提取出參數(shù)里面的要啟動的類的名字invokeStaticMain(args.startClass, args.startArgs, classLoader); }

3.1.7 RuntimeInit.invokeStaticMain

主要調(diào)用了 invokeStaticMain 方法:

private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader)throws ZygoteInit.MethodAndArgsCaller {Class<?> cl;try {/** className 為通過 Socket 客戶端(AMS)傳遞過來的一系列參數(shù)中的其中一個,這里獲取到的值為傳"com.android.app.ActivityThread",然后通過反射得到 ActivityThread 類 **/cl = Class.forName(className, true, classLoader);} catch (ClassNotFoundException ex) {throw new RuntimeException("Missing class when invoking static main " + className, ex);}Method m;try {// 找到 ActivityThread 類的 main 方法m = cl.getMethod("main", new Class[] { String[].class });} catch (NoSuchMethodException ex) {throw new RuntimeException("Missing static main on " + className, ex);} catch (SecurityException ex) {throw new RuntimeException("Problem getting static main on " + className, ex);}int modifiers = m.getModifiers();if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {throw new RuntimeException("Main method is not public and static on " + className);}/** 將 main 方法包裝在 ZygoteInit.MethodAndArgsCaller 類中并作為異常拋出捕獲異常的地方在上一小節(jié)中 ZygoteInit.java 的 main 方法 **/throw new ZygoteInit.MethodAndArgsCaller(m, argv); }

3.1.8 MethodAndArgsCaller.run

回到 ZygoteInit 的 main 方法:

public static void main(String argv[]) {...closeServerSocket();} catch (MethodAndArgsCaller caller) {// 接收到 caller 對象后調(diào)用它的 run 方法caller.run();} catch (RuntimeException ex) {Log.e(TAG, "Zygote died with exception", ex);closeServerSocket();throw ex;} }

跟 system_server 進程的啟動過程一樣,這里同樣通過拋出異常的方式來清空調(diào)用 ActivityThread.main 之前的方法棧幀。

ZygoteInit 的 MethodAndArgsCaller 類是一個 Exception 類,同時也實現(xiàn)了 Runnable 接口:

public static class MethodAndArgsCaller extends Exceptionimplements Runnable {private final Method mMethod;private final String[] mArgs;public MethodAndArgsCaller(Method method, String[] args) {mMethod = method;mArgs = args;}public void run() {try {// 調(diào)用傳遞過來的 mMethodmMethod.invoke(null, new Object[] { mArgs });} catch (IllegalAccessException ex) {throw new RuntimeException(ex);} catch (InvocationTargetException ex) {...}} }

3.1.9 ActivityThread .main

最后通過反射調(diào)用到 ActivityThread 的 main 方法:

public static void main(String[] args) {...Environment.initForCurrentUser();...Process.setArgV0("<pre-initialized>");// 創(chuàng)建主線程 LooperLooper.prepareMainLooper();ActivityThread thread = new ActivityThread();// attach 到系統(tǒng)進程thread.attach(false);if (sMainThreadHandler == null) {sMainThreadHandler = thread.getHandler();}// 主線程進入輪詢狀態(tài)Looper.loop();// 拋出異常說明輪詢出現(xiàn)問題throw new RuntimeException("Main thread loop unexpectedly exited"); }

3.2 小結(jié)

zygote 進程作為 Socket 服務(wù)端在接收到作為客戶端的 AMS 發(fā)送過來的請求和參數(shù)之后,fock 出新的進程并根據(jù)各種參數(shù)進程了初始化的工作,這個過程和 zygote 啟動 system_server 進程的過程如出一轍,時序圖如下所示:

4. ActivityThread —— Activity

4.1 調(diào)用過程分析

4.1.1 ActivityThread.attach

上一小節(jié)的最后,ActivityThread 的 main 通過反射被運行起來了,接著會調(diào)用 ActivityThread 的 attach 方法:

private void attach(boolean system) {...mSystemThread = system;if (!system) {...// 獲取 ActivityManagerProxy 對象final IActivityManager mgr = ActivityManagerNative.getDefault();try {// 通過 Binder 調(diào)用 AMS 的 attachApplication 方法mgr.attachApplication(mAppThread);} catch (RemoteException ex) {throw ex.rethrowFromSystemServer();}} else {...}... }

這里,我們再一次通過 Binder IPC 機制跟 AMS 通信,通信模型跟前面 Launcher App 調(diào)用 AMS 的 startActivity 方法一樣,getDefault 過程不重復(fù)分析,這次是調(diào)用了 AMS 的 attachApplication 方法,注意這里將 ApplicationThead 類型的 mAppThread 對象作為參數(shù)傳遞了過去,ApplicationThead 是 ActivityThread 的一個內(nèi)部類,后面我們會講到,先查看 AMP 的 attachApplication 方法:

4.1.2 ActivityManagerProxy.attachApplication

public void attachApplication(IApplicationThread app) throws RemoteException {...// 調(diào)用 asBinder 方法使其能夠跨進程傳輸data.writeStrongBinder(app.asBinder());// 通過 transact 方法將數(shù)據(jù)交給 Binder 驅(qū)動mRemote.transact(ATTACH_APPLICATION_TRANSACTION, data, reply, 0); reply.readException();data.recycle();reply.recycle(); }

4.1.3 ActivityManagerNative.onTransact

public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {switch (code) {...case ATTACH_APPLICATION_TRANSACTION: {data.enforceInterface(IActivityManager.descriptor);// 獲取 ApplicationThread 的代理對象,這里返回的是 ApplicationThreadNative(ATN)// 的內(nèi)部類:ApplicationThreadProxy(ATP) 對象IApplicationThread app = ApplicationThreadNative.asInterface(data.readStrongBinder());if (app != null) {// 委托給 AMS 執(zhí)行attachApplication(app);}reply.writeNoException();return true;}...} }

asInterface 將 ActivityThread 對象轉(zhuǎn)換成了 ApplicationThreadNative(ATN) 的 Binder 代理對象 ApplicationThreadProxy(ATP),并作為參數(shù)傳給 attachApplication 方法,其中 ATP 是 ATN 的內(nèi)部類。

4.1.4 ActivityManagerService.attachApplication

public final void attachApplication(IApplicationThread thread) {synchronized (this) {int callingPid = Binder.getCallingPid();final long origId = Binder.clearCallingIdentity();attachApplicationLocked(thread, callingPid);Binder.restoreCallingIdentity(origId);} }

4.1.5 ActivityManagerService.attachApplicationLocked

private final boolean attachApplicationLocked(IApplicationThread thread, int pid) {ProcessRecord app;...try {// 綁定死亡通知AppDeathRecipient adr = new AppDeathRecipient(app, pid, thread);thread.asBinder().linkToDeath(adr, 0);app.deathRecipient = adr;} catch (RemoteException e) {app.resetPackageList(mProcessStats);// 如果 system_server 進程死亡則重新啟動進程startProcessLocked(app, "link fail", processName); return false;}...try {...// 獲取應(yīng)用appInfoApplicationInfo appInfo = app.instrumentationInfo != null? app.instrumentationInfo : app.info;...// 綁定應(yīng)用thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,isRestrictedBackupMode || !normalMode, app.persistent,new Configuration(mConfiguration), app.compat,getCommonServicesLocked(app.isolated),mCoreSettingsObserver.getCoreSettingsLocked());...} catch (Exception e) {app.resetPackageList(mProcessStats);app.unlinkDeathRecipient();// bindApplication 失敗也要重啟進程startProcessLocked(app, "bind fail", processName);return false;}// 如果是 Activity: 檢查最頂層可見的Activity是否等待在該進程中運行if (normalMode) {try {if (mStackSupervisor.attachApplicationLocked(app)) {didSomething = true;}} catch (Exception e) {badApp = true;}}// 如果是 Service: 尋找所有需要在該進程中運行的服務(wù)if (!badApp) {try {didSomething |= mServices.attachApplicationLocked(app, processName);} catch (Exception e) {badApp = true;}}// 如果是 BroadcastReceiver: 檢查是否在這個進程中有下一個廣播接收者if (!badApp && isPendingBroadcastProcessLocked(pid)) {try {didSomething |= sendPendingBroadcastsLocked(app);} catch (Exception e) {badApp = true;}}// 檢查是否在這個進程中有下一個 backup 代理if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {ensurePackageDexOpt(mBackupTarget.appInfo.packageName);try {thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,compatibilityInfoForPackageLocked(mBackupTarget.appInfo),mBackupTarget.backupMode);} catch (Exception e) {badApp = true;}}if (badApp) { // 殺掉 badAppapp.kill("error during init", true);handleAppDiedLocked(app, false, true);return false;}if (!didSomething) {// 更新 adj(組件的權(quán)值)updateOomAdjLocked(); }return true; }

首先,通過 ATP 使用 Binder 向 ATN 發(fā)起 bindApplication 請求,然后通過 normalMode 字段判斷是否為 Activity,如果是則執(zhí)行 ActivityStackSupervisor 的 attachApplicationLocked 方法。

4.1.5.1 ActivityThread.java::ApplicationThread.bindApplication

thread 對象類型是 ATP,通過 Binder 驅(qū)動調(diào)到了 ATN 的方法,ATN 是一個抽象類,它的實現(xiàn)都委托給了 ApplicationThread(這跟 AMS 跟 AMN 的關(guān)系一樣),ApplicationThread 作為 ActivityThread 的內(nèi)部類存在,它的 binderApplication 方法如下:

ActivityThread.java::ApplicationThread:

public final void bindApplication(String processName, ApplicationInfo appInfo,List<ProviderInfo> providers, ComponentName instrumentationName, ProfilerInfo profilerInfo,Bundle instrumentationArgs, IInstrumentationWatcher instrumentationWatcher,IUiAutomationConnection instrumentationUiConnection, int debugMode, booleanenableOpenGlTrace, boolean isRestrictedBackupMode, boolean persistent, Configurationconfig, CompatibilityInfo compatInfo, Map<String, IBinder> services, Bundle coreSettings) {if (services != null) {// 將services緩存起來, 減少binder檢索服務(wù)的次數(shù)ServiceManager.initServiceCache(services);}...// 發(fā)送消息 H.BIND_APPLICATION 給 Handler 對象sendMessage(H.BIND_APPLICATION, data); }

H 是 ActivityThread 中的一個 Handler 對象,用于處理發(fā)送過來的各種消息:

private class H extends Handler {public static final int BIND_APPLICATION = 110;public void handleMessage(Message msg) {...case BIND_APPLICATION:Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");AppBindData data = (AppBindData)msg.obj;handleBindApplication(data);Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);break;...} }

調(diào)用了 handleBindApplication 方法:

private void handleBindApplication(AppBindData data) {// 獲取 LoadedApk 對象data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo);...// 創(chuàng)建 ContextImpl 上下文final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);...// 創(chuàng)建 Instrumentation 對象if (data.instrumentationName != null) {...} else {mInstrumentation = new Instrumentation();}try {// 調(diào)用 LoadedApk 的 makeApplication 方法創(chuàng)建 ApplicationApplication app = data.info.makeApplication(data.restrictedBackupMode, null);mInitialApplication = app;...mInstrumentation.onCreate(data.instrumentationArgs);// 調(diào)用 Application.onCreate 方法mInstrumentation.callApplicationOnCreate(app);} finally {StrictMode.setThreadPolicy(savedPolicy);} }

4.1.5.2 ActivityStackSupervisor.attachApplicationLocked

在 4.1.4 小節(jié)中通過 Binder 向 ActivityThread 發(fā)起 bindApplication 請求后,會根據(jù)啟動組件的類型去做相應(yīng)的處理,如果是 Acitivity,則會調(diào)用 ActivityStackSupervisor 的 attachApplicationLocked 方法:

boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {final String processName = app.processName;boolean didSomething = false;for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {final ActivityStack stack = stacks.get(stackNdx);if (!isFrontStack(stack)) {continue;}// 獲取前臺stack中棧頂?shù)谝粋€非 finishing 狀態(tài)的 ActivityActivityRecord hr = stack.topRunningActivityLocked(null);if (hr != null) {if (hr.app == null && app.uid == hr.info.applicationInfo.uid && processName.equals(hr.processName)) {try {// 真正的啟動 Activityif (realStartActivityLocked(hr, app, true, true)) {didSomething = true;}} catch (RemoteException e) {throw e;}}}}}...return didSomething; }

4.1.5.2.1 ActivityStackSupervisor.realStartActivityLocked

前面 2.1.8 ActivityStackSupervisor.startSpecificActivityLocked 小節(jié)中分析過,如果當(dāng)前 Activity 依附的 Application 已經(jīng)被啟動,則調(diào)用 realStartActivityLocked 方法,否則創(chuàng)建新的進程,再創(chuàng)建新的進程之后,兩個流程的在這里合并起來了:

final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app, boolean andResume, boolean checkConfig) throws RemoteException {...final ActivityStack stack = task.stack;try {...app.forceProcessStateUpTo(mService.mTopProcessState);// 通過 Binder 調(diào)用 ApplicationThread 的 scheduleLaunchActivity 方法app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration),new Configuration(stack.mOverrideConfig), r.compat, r.launchedFromPackage,task.voiceInteractor, app.repProcState, r.icicle, r.persistentState, results,newIntents, !andResume, mService.isNextTransitionForward(), profilerInfo);...} catch (RemoteException e) {if (r.launchFailed) {// 第二次啟動失敗,則結(jié)束該 ActivitymService.appDiedLocked(app);stack.requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null,"2nd-crash", false);return false;}// 第一個啟動失敗,則重啟進程app.activities.remove(r);throw e;}...return true; }

這里有一次使用 Binder 調(diào)用 ApplicationThread 的 scheduleLaunchActivity 方法。

4.1.5.2.2 ApplicationThread.scheduleLaunchActivity

public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident, ActivityInfo info, Configuration curConfig, Configuration overrideConfig, CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor, int procState, Bundle state, PersistableBundle persistentState, List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents, boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) {...updateProcessState(procState, false);ActivityClientRecord r = new ActivityClientRecord();...sendMessage(H.LAUNCH_ACTIVITY, r);}

上面提到過,H 是 ActivityThread 中一個 Handler 類,它接收到 LAUNCH_ACTIVITY 消息后會調(diào)用 handleLaunchActivity 方法。

4.1.5.2.3 ActivityThread.handleLaunchActivity

private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {...// 初始化 WMSWindowManagerGlobal.initialize();// 執(zhí)行 performLaunchActivity 方法Activity a = performLaunchActivity(r, customIntent);if (a != null) {r.createdConfig = new Configuration(mConfiguration);Bundle oldState = r.state;// 執(zhí)行 handleResumeActivity 方法,最終調(diào)用 onStart 和 onResume 方法handleResumeActivity(r.token, false, r.isForward,!r.activity.mFinished && !r.startsNotResumed);if (!r.activity.mFinished && r.startsNotResumed) {r.activity.mCalled = false;mInstrumentation.callActivityOnPause(r.activity);r.paused = true;}} else {// 停止該 ActivityActivityManagerNative.getDefault().finishActivity(r.token, Activity.RESULT_CANCELED, null, false);} }

4.1.4.2.4 ApplicationThread.performLaunchActivity

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {...Activity activity = null;try {java.lang.ClassLoader cl = r.packageInfo.getClassLoader();// Instrumentation 中使用反射創(chuàng)建 Activityactivity = mInstrumentation.newActivity(cl, component.getClassName(), r.intent);...} catch (Exception e) {...}try {// 創(chuàng)建 Application 對象并調(diào)用 Application 的 onCreate 方法Application app = r.packageInfo.makeApplication(false, mInstrumentation);if (activity != null) {...// attach 到 Window 上activity.attach(appContext, this, getInstrumentation(), r.token,r.ident, app, r.intent, r.activityInfo, title, r.parent,r.embeddedID, r.lastNonConfigurationInstances, config,r.referrer, r.voiceInteractor);if (customIntent != null) {activity.mIntent = customIntent;}r.lastNonConfigurationInstances = null;activity.mStartedActivity = false;int theme = r.activityInfo.getThemeResource();if (theme != 0) {// 設(shè)置主題activity.setTheme(theme);}activity.mCalled = false;if (r.isPersistable()) {// 重新創(chuàng)建的 ActivitymInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);} else {// 第一次創(chuàng)建的 ActivitymInstrumentation.callActivityOnCreate(activity, r.state);}...}...} catch (Exception e) {...}return activity; }

4.1.5.2.5 Instrumentation.callActivityOnCreate

public void callActivityOnCreate(Activity activity, Bundle icicle,PersistableBundle persistentState) {prePerformCreate(activity);// 調(diào)用 Activity 的 performCreate 方法activity.performCreate(icicle, persistentState);postPerformCreate(activity); }

4.1.5.2.6 Activity.performCreate

final void performCreate(Bundle icicle, PersistableBundle persistentState) {restoreHasCurrentPermissionRequest(icicle);onCreate(icicle, persistentState);mActivityTransitionState.readState(icicle);performCreateCommon(); }

終于,onCreate 方法被調(diào)用了!!!

4.2 小結(jié)

從 ActivityThread 到最終 Activity 被創(chuàng)建及生命周期被調(diào)用,核心過程涉及到了三次 Binder IPC 過程,分別是:ActivityThread 調(diào)用 AMS 的 attachApplication 方法、AMS 調(diào)用 ApplicationThread 的 bindApplication 方法、ASS 調(diào)用 Application 的 attachApplicationLocked 方法,整個過程的時序圖如下:

5. 總結(jié)

縱觀整個過程,從 Launcher 到 AMS、從 AMS 再到 Zygote、再從 Zygote 到 ActivityThread,最后在 ActivitThread 中層層調(diào)用到 Activity 的生命周期方法,中間涉及到了無數(shù)的細(xì)節(jié),但總體上脈絡(luò)還是非常清晰的,各個 Android 版本的 Framework 層代碼可以某些過程的實現(xiàn)不太一樣,但是整個調(diào)用流程大體上也是相同的,借用 Gityuan 大神的一張圖作為結(jié)尾:

系列文章

AJie:按下電源鍵后竟然發(fā)生了這一幕 —— Android 系統(tǒng)啟動流程分析?zhuanlan.zhihu.comAJie:App 竟然是這樣跑起來的 —— Android App/Activity 啟動流程分析?zhuanlan.zhihu.comAJie:屏幕上內(nèi)容究竟是怎樣畫出來的 —— Android View 工作原理詳解?zhuanlan.zhihu.com

參考文章

startActivity啟動過程分析 - Gityuan博客 | 袁輝輝的技術(shù)博客

Android深入四大組件(一)應(yīng)用程序啟動過程(前篇)

如果你對文章內(nèi)容有疑問或者有不同的意見,歡迎留言,我們一同探討。

總結(jié)

以上是生活随笔為你收集整理的c++builder启动了怎么停止_App 竟然是这样跑起来的 —— Android App/Activity 启动流程分析...的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。