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

}

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 附属的 Application
ProcessRecord app = mService.getProcessRecordLocked(r.processName,
r.info.applicationInfo.uid, true);
r.task.stack.setLaunchTime®;
// 如果 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, 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) {

// 调用 zygoteSendArgsAndGetResult 方法,传入 openZygoteSocketIfNeeded 的返回值
return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote);
}
}

2.1.15 Process.zygoteSendArgsAndGetResult、Process.openZygoteSocketIfNeeded

查看 zygoteSendArgsAndGetResult 方法:

private static ProcessStartResult zygoteSendArgsAndGetResult(
ZygoteState zygoteState, ArrayList 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 Exception
implements Runnable {

private final Method mMethod;
private final String[] mArgs;

public MethodAndArgsCaller(Method method, String[] args) {
mMethod = method;
mArgs = args;
}
public void run() {
try {
// 调用传递过来的 mMethod
mMethod.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(“”);
// 创建主线程 Looper
Looper.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 {

// 获取应用appInfo
ApplicationInfo 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) {
// 杀掉 badApp
app.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 providers, ComponentName instrumentationName, ProfilerInfo profilerInfo,
Bundle instrumentationArgs, IInstrumentationWatcher instrumentationWatcher,
IUiAutomationConnection instrumentationUiConnection, int debugMode, boolean
enableOpenGlTrace, boolean isRestrictedBackupMode, boolean persistent, Configuration
config, 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 方法创建 Application
Application 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 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 状态的 Activity
ActivityRecord hr = stack.topRunningActivityLocked(null);
if (hr != null) {
if (hr.app == null && app.uid == hr.info.applicationInfo.uid && processName.equals(hr.processName)) {
try {
// 真正的启动 Activity
if (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.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) {
// 第二次启动失败,则结束该 Activity
mService.appDiedLocked(app);
stack.requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null,
“2nd-crash”, false);
return false;
}
// 第一个启动失败,则重启进程
app.activities.remove®;
throw e;
}

return true;
}

这里有一次使用 Binder 调用 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 pendingResults,
List pendingNewIntents, boolean notResumed, boolean isForward,
ProfilerInfo profilerInfo) {

updateProcessState(procState, false);
ActivityClientRecord r = new ActivityClientRecord();

sendMessage(H.LAUNCH_ACTIVITY, r);
}

上面提到过,H 是 ActivityThread 中一个 Handler 类,它接收到 LAUNCH_ACTIVITY 消息后会调用 handleLaunchActivity 方法。

4.1.5.2.3 ActivityThread.handleLaunchActivity

private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {

// 初始化 WMS
WindowManagerGlobal.initialize();
// 执行 performLaunchActivity 方法
Activity a = performLaunchActivity(r, customIntent);
if (a != null) {
r.createdConfig = new Configuration(mConfiguration);
Bundle oldState = r.state;
// 执行 handleResumeActivity 方法,最终调用 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 {
// 停止该 Activity
ActivityManagerNative.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 中使用反射创建 Activity
activity = mInstrumentation.newActivity(cl, component.getClassName(), r.intent);

} catch (Exception e) {

}

try {
// 创建 Application 对象并调用 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) {
// 设置主题
activity.setTheme(theme);
}

activity.mCalled = false;
if (r.isPersistable()) {
// 重新创建的 Activity
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
// 第一次创建的 Activity
mInstrumentation.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);
// 调用 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 方法被调用了!!!

4.2 小结

从 ActivityThread 到最终 Activity 被创建及生命周期被调用,核心过程涉及到了三次 Binder IPC 过程,分别是:ActivityThread 调用 AMS 的 attachApplication 方法、AMS 调用 ApplicationThread 的 bindApplication 方法、ASS 调用 Application 的 attachApplicationLocked 方法,整个过程的时序图如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

5. 总结

纵观整个过程,从 Launcher 到 AMS、从 AMS 再到 Zygote、再从 Zygote 到 ActivityThread,最后在 ActivitThread 中层层调用到 Activity 的生命周期方法,中间涉及到了无数的细节,但总体上脉络还是非常清晰的,各个 Android 版本的 Framework 层代码可以某些过程的实现不太一样,但是整个调用流程大体上也是相同的,借用 Gityuan 大神的一张图作为结尾:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
系列文章
按下电源键后竟然发生了这一幕 —— Android 系统启动流程分析
App 竟然是这样跑起来的 —— Android App/Activity 启动流程分析(本文)
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img

img

img

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)

最后

总之啊,家里没矿的同学们,如果你们想以后的日子过得好一些,多想想你们的业余时间怎么安排吧;

技术方面的提升肯定是重中之重,但是技术外的一些“软实力”也不能完全忽视,很多时候升职确实是因为你的技术足够强,但也与你的“软实力”密切相关

在这我也分享一份大佬自己收录整理的 Android学习PDF+架构视频+面试文档+源码笔记 ,还有高级架构技术进阶脑图、Android开发面试专题资料,高级进阶架构资料这些都是我闲暇还会反复翻阅并给下属员工学习的精品资料。在脑图中,每个知识点专题都配有相对应的实战项目,可以有效的帮助大家掌握知识点。

总之也是在这里帮助大家学习提升进阶,也节省大家在网上搜索资料的时间来学习,也可以分享给身边好友一起学习

相信自己,没有做不到的,只有想不到的

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

存中…(img-qbzGPpnK-1713294020762)]

[外链图片转存中…(img-TZvsUvUO-1713294020763)]

[外链图片转存中…(img-F69gLNRi-1713294020764)]

[外链图片转存中…(img-kB1Loiq2-1713294020765)]

[外链图片转存中…(img-4BV36a46-1713294020766)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)

最后

总之啊,家里没矿的同学们,如果你们想以后的日子过得好一些,多想想你们的业余时间怎么安排吧;

技术方面的提升肯定是重中之重,但是技术外的一些“软实力”也不能完全忽视,很多时候升职确实是因为你的技术足够强,但也与你的“软实力”密切相关

在这我也分享一份大佬自己收录整理的 Android学习PDF+架构视频+面试文档+源码笔记 ,还有高级架构技术进阶脑图、Android开发面试专题资料,高级进阶架构资料这些都是我闲暇还会反复翻阅并给下属员工学习的精品资料。在脑图中,每个知识点专题都配有相对应的实战项目,可以有效的帮助大家掌握知识点。

总之也是在这里帮助大家学习提升进阶,也节省大家在网上搜索资料的时间来学习,也可以分享给身边好友一起学习

[外链图片转存中…(img-gahKx8lr-1713294020767)]

[外链图片转存中…(img-y1UlWLbz-1713294020768)]

相信自己,没有做不到的,只有想不到的

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

  • 17
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值