写点什么

App 竟然是这样跑起来的 —— Android App_Activity 启动流程分析

用户头像
Android架构
关注
发布于: 刚刚

IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask) {...


// 调用 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) {// 调用 ActivityStack 的 resumeTopActivityUncheckedLocked 方法 mFocusedStack.resumeTopActivityUncheckedLocked(null, null);}return false;}

2.1.7 ActivityStack.resumeTopActivityUncheckedLocked

查看 ActivityStack 的 resumeTopActivityUncheckedLocked 方法:


boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {...try {...// 调用 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);// 调用 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) {// 当前 Activity 附属的 ApplicationProcessRecord app = mService.getProcessRecordLocked(r.processName,r.info.applicationInfo.uid, true);r.task.stack.setLaunchTime(r);// 如果 Application 已经运行 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);}


首先,在方法中获取了当前 Activity 附属的 Application,如果已经在运行了,说明这个 App 是已经被启动过了的,这时候调用 realStartActivityLocked 方法就可以进入下一步的流程了,同一个 App 中不同 Activity 的相互启动就是走的这个流程。当 Application 没有运行的时候,就需要调用 AMS 的 startProcessLocked 方法启动一个进程去承载它然后完成后续的工作,顺便铺垫一下,当新进程被启动完成后还会调用回到这个方法,查看 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

调用 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

调用 startProcessLocked 的重载方法:


private final void startProcessLocked(ProcessRecord app, String hostingType,String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs){...try {...// 调用 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 {// 调用 startViaZygote 方法 return startViaZygote(processClass, niceName, uid, gid, gids,debugFlags, mountExternal, target


《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
浏览器打开:qq.cn.hn/FTe 免费领取
复制代码


SdkVersion, 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) {...// 调用 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 服务端(即 zygote)返回新创建的进程 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 服务端,也就是 zygote 进程返回创建新进程的结果,这里 zygoteState 参数是由 openZygoteSocketIfNeeded 方法返回的,openZygoteSocketIfNeeded 方法则负责根据 abi 向 Zygote 进程发起连接请求:


private static ZygoteState openZygoteSocketIfNeeded(String abi) throws ZygoteStartFailedEx {if (primaryZygoteState == null || primaryZygoteState.isClosed()) {try {// 向主 zygote 发起 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 {// 当主 zygote 没能匹配成功,则采用第二个 zygote,发起 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 小结

如果是从桌面新启动一个 App 中的 Activity,此时是没有进程去承载这个 App 的,因此需要通过 AMS 向 zygote 继承发起请求去完成这个任务,AMS 运行在 system_server 进程中,它通过 Socket 向 zygote 发起 fock 进程的请求,从 AMS 开始的调用时序图如下:


3. zygote —— ActivityThread

3.1 调用过程分析

3.1.1 ZygoteInit.main

Android 系统启动流程分析 文中提到过 zygote 进程的其中一项任务就是:


调用 registerZygoteSocket() 函数建立 Socket 通道,使 zygote 进程成为 Socket 服务端,并通过 runSelectLoop() 函数等待 ActivityManagerService 发送请求创建新的应用程序进程。


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 {...// 循环读取状态 while (true) {...for (int i = pollFds.length - 1; i >= 0; --i) {// 读取的状态不是客户端连接或者数据请求时,进入下一次循环 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 发送过来的请求// runOnce 方法创建一个新的应用程序进程 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 客户端发送过来的参数列表 args = readArgumentList();descriptors = mSocket.getAncillaryFileDescriptors();} catch (IOException ex) {// EOF reached.closeSocket();return true;}...try {// 将 socket 客户端传递过来的参数,解析成 Arguments 对象格式 parsedArgs = new Arguments(args);...// 同样调用 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) {// 子进程执行 IoUtils.closeQuietly(serverPipeFd);serverPipeFd = null;// 进入子进程流程 handleChildProc(parsedArgs, descriptors, childPipeFd, newStderr);return true;} else {// 父进程执行 IoUtils.closeQuietly(childPipeFd);childPipeFd = null;return handleParentProc(pid, descriptors, serverPipeFd, parsedArgs);}} finally {IoUtils.closeQuietly(childPipeFd);IoUtils.closeQuietly(serverPipeFd);}}

3.1.4 ZygoteConnection.handleChildProc

首先解析 Socket 客户端传过来的参数,Zygote.java 的 forkAndSpecialize 返回的 pid == 0 的时候表示此时在 fock 出来的子进程中执行,继续调用 handleChildProc 方法,并将参数继续层层传递:


private void handleChildProc(Arguments parsedArgs, FileDescriptor[]descriptors, FileDescriptor pipeFd, PrintStream newStderr) throws ZygoteInit.MethodAndArgsCaller {/*由于 fock 出来的 system_server 进程会复制 zygote 进程的地址空间,因此它也得到了 zygote 进程中的 Socket,这个 Socket 对它来说并无用处,这里将其关闭*/closeSocket();ZygoteInit.closeServerSocket();...if (parsedArgs.niceName != null) {// 设置进程名 Process.setArgV0(parsedArgs.niceName);}


if (parsedArgs.invokeWith != null) {...} else {// 调用 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();// 初始化一些通用的设置 commonInit();/***通过 Native 层中 AndroidRuntime.cpp 的 JNI 方法最终调用 app_main.cpp 的*onZygoteInit 方法启动 Binder 线程池, 使 system_server 进程可以使用 Binder *与其他进程通信**/nativeZygoteInit();applicationInit(targetSdkVersion, argv, classLoader);}

3.1.6 RuntimeInit.applicationInit

继续调用 applicationInit 方法:


private static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)throws ZygoteInit.MethodAndArgsCaller {...// 提取出参数里面的要启动的类的名字 invokeStaticMain(args.startClass, args.startArgs, classLoader);}

3.1.7 RuntimeInit.invokeStaticMain

主要调用了 invokeStaticMain 方法:


private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader)throws ZygoteInit.MethodAndArgsCaller {Class<?> cl;try {/** className 为通过 Socket 客户端(AMS)传递过来的一系列参数中的其中一个,这里获取到的值为传"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 类中并作为异常抛出捕获异常的地方在上一小节中 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 对象后调用它的 run 方法 caller.run();} catch (RuntimeException ex) {Log.e(TAG, "Zygote died with exception", ex);closeServerSocket();throw ex;}}


跟 system_server 进程的启动过程一样,这里同样通过抛出异常的方式来清空调用 ActivityThread.main 之前的方法栈帧。


ZygoteInit 的 MethodAndArgsCaller 类是一个 Exception 类,同时也实现了 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 {// 调用传递过来的 mMethodmMethod.invoke(null, new Object[] { mArgs });} catch (IllegalAccessException ex) {throw new RuntimeException(ex);} catch (InvocationTargetException ex) {...}}}

3.1.9 ActivityThread .main

最后通过反射调用到 ActivityThread 的 main 方法:


public static void main(String[] args) {...Environment.initForCurrentUser();...Process.setArgV0("<pre-initialized>");// 创建主线程 LooperLooper.prepareMainLooper();


ActivityThread thread = new ActivityThread();// attach 到系统进程 thread.attach(false);


if (sMainThreadHandler == null) {sMainThreadHandler = thread.getHandler();}


// 主线程进入轮询状态 Looper.loop();


// 抛出异常说明轮询出现问题 throw new RuntimeException("Main thread loop unexpectedly exited");}

3.2 小结

zygote 进程作为 Socket 服务端在接收到作为客户端的 AMS 发送过来的请求和参数之后,fock 出新的进程并根据各种参数进程了初始化的工作,这个过程和 zygote 启动 system_server 进程的过程如出一辙,时序图如下所示:


4. ActivityThread —— Activity

4.1 调用过程分析

4.1.1 ActivityThread.attach

上一小节的最后,ActivityThread 的 main 通过反射被运行起来了,接着会调用 ActivityThread 的 attach 方法:


private void attach(boolean system) {...mSystemThread = system;if (!system) {...// 获取 ActivityManagerProxy 对象 final IActivityManager mgr = ActivityManagerNative.getDefault();try {// 通过 Binder 调用 AMS 的 attachApplication 方法 mgr.attachApplication(mAppThread);} catch (RemoteException ex) {throw ex.rethrowFromSystemServer();}} else {...}...}


这里,我们再一次通过 Binder IPC 机制跟 AMS 通信,通信模型跟前面 Launcher App 调用 AMS 的 startActivity 方法一样,getDefault 过程不重复分析,这次是调用了 AMS 的 attachApplication 方法,注意这里将 ApplicationThead 类型的 mAppThread 对象作为参数传递了过去,ApplicationThead 是 ActivityThread 的一个内部类,后面我们会讲到,先查看 AMP 的 attachApplication 方法:

4.1.2 ActivityManagerProxy.attachApplication

public void attachApplication(IApplicationThread app) throws RemoteException {...// 调用 asBinder 方法使其能够跨进程传输 data.writeStrongBinder(app.asBinder());// 通过 transact 方法将数据交给 Binder 驱动 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)// 的内部类:ApplicationThreadProxy(ATP) 对象 IApplicationThread app = ApplicationThreadNative.asInterface(data.readStrongBinder());if (app != null) {// 委托给 AMS 执行 attachApplication(app);}reply.writeNoException();return true;}...}}


asInterface 将 ActivityThread 对象转换成了 ApplicationThreadNative(ATN) 的 Binder 代理对象 ApplicationThreadProxy(ATP),并作为参数传给 attachApplication 方法,其中 ATP 是 ATN 的内部类。

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 {...// 获取应用 appInfoApplicationInfo appInfo = app.instrumentationInfo != null? app.instrumentationInfo : app.info;...// 绑定应用 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: 寻找所有需要在该进程中运行的服务 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(组件的权值)updateOomAdjLocked();}return true;}


首先,通过 ATP 使用 Binder 向 ATN 发起 bindApplication 请求,然后通过 normalMode 字段判断是否为 Activity,如果是则执行 ActivityStackSupervisor 的 attachApplicationLocked 方法。

4.1.5.1 ActivityThread.java::ApplicationThread.bindApplication

thread 对象类型是 ATP,通过 Binder 驱动调到了 ATN 的方法,ATN 是一个抽象类,它的实现都委托给了 ApplicationThread(这跟 AMS 跟 AMN 的关系一样),ApplicationThread 作为 ActivityThread 的内部类存在,它的 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 检索服务的次数 ServiceManager.initServiceCache(services);}...// 发送消息 H.BIND_APPLICATION 给 Handler 对象 sendMessage(H.BIND_APPLICATION, data);}


H 是 ActivityThread 中的一个 Handler 对象,用于处理发送过来的各种消息:


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;...}}


调用了 handleBindApplication 方法:


private void handleBindApplication(AppBindData data) {// 获取 LoadedApk 对象 data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo);...// 创建 ContextImpl 上下文 final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);...// 创建 Instrumentation 对象 if (data.instrumentationName != null) {...} else {mInstrumentation = new Instrumentation();}


try {// 调用 LoadedApk 的 makeApplication 方法创建 ApplicationApplication app = data.info.makeApplication(data.restrictedBackupMode, null);mInitialApplication = app;...mInstrumentation.onCreate(data.instrumentationArgs);// 调用 Application.onCreate 方法 mInstrumentation.callApplicationOnCreate(app);} finally {StrictMode.setThreadPolicy(savedPolicy);}}

4.1.5.2 ActivityStackSupervisor.attachApplicationLocked

4.1.4 小节中通过 Binder 向 ActivityThread 发起 bindApplication 请求后,会根据启动组件的类型去做相应的处理,如果是 Acitivity,则会调用 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 中栈顶第一个非 finishing 状态的 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 小节中分析过,如果当前 Activity 依附的 Application 已经被启动,则调用 realStartActivityLocked 方法,否则创建新的进程,再创建新的进程之后,两个流程的在这里合并起来了:


final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app, boolean andResume, boolean checkConfig) throws RemoteException {...final ActivityStack stack = task.stack;try {...app.forceProcessStateUpTo(mService.mTopProcessState);// 通过 Binder 调用 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,

用户头像

Android架构

关注

还未添加个人签名 2021.10.31 加入

还未添加个人简介

评论

发布
暂无评论
App 竟然是这样跑起来的 —— Android App_Activity 启动流程分析