在之前的文章讲了app进程大概的启动过程(https://blog.csdn.net/qq_36063677/article/details/125638137),这篇文章细致的分析一下app进程从zygote进程fork出来到onCreate等生命周期方法被执行的过程。
Android应用程序具有两个特点:
从zygote进程的启动过程(https://blog.csdn.net/qq_36063677/article/details/129235187)可以看到,zygote在fork出一个子进程后,handleChildProc()函数开始处理新进程初始化操作,调用ZygoteInit.zygoteInit():
//ZygoteInit.java
public static final Runnable zygoteInit(int targetSdkVersion, long[] disabledCompatChanges,
String[] argv, ClassLoader classLoader) {
if (RuntimeInit.DEBUG) {
Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from zygote");
}
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit");
RuntimeInit.redirectLogStreams();
RuntimeInit.commonInit();
// 1. 使进程支持IPC(binder进程间通信)
ZygoteInit.nativeZygoteInit();
// 2. 调用AcitivtyThraed.main()
return RuntimeInit.applicationInit(targetSdkVersion, disabledCompatChanges, argv,
classLoader);
}
ZygoteInit.nativeZygoteInit()是一个jni实现的native方法,方法实现是调用AndroidRuntime对象的onZygoteInit():
//AndoridRuntime.cpp
static AndroidRuntime* gCurRuntime = NULL;
static void com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env, jobject clazz)
{
gCurRuntime->onZygoteInit();
}
AppRuntime继承了AndroidRuntime了,并且实现了onZygoteInit()方法,关于安卓runtime机制后续分析,现在这里挖个坑。
AppRuntime类在熟悉的app_process模块中定义:
// app_main.cpp
class AppRuntime : public AndroidRuntime
{
......
virtual void onZygoteInit()
{
sp<ProcessState> proc = ProcessState::self();
ALOGV("App process: starting thread pool.\n");
proc->startThreadPool();
}
}
又看到了熟悉的ProcessState,binder通信绕不开的对象,关于ProcessState和IPCThreadState,其都被定义在libbinder模块中。
回到ProcessState,startThreadPool调用spawnPooledThread()方法,创建PoolThread线程类,并且启动这个线程。
//ProcessState.cpp
class PoolThread : public Thread {
public:
explicit PoolThread(bool isMain)
: mIsMain(isMain)
{}
protected:
virtual bool threadLoop()
{
IPCThreadState::self()->joinThreadPool(mIsMain);
return false;
}
const bool mIsMain;
};
void ProcessState::startThreadPool() {
AutoMutex _l(mLock);
if (!mThreadPoolStarted) {
mThreadPoolStarted = true;
spawnPooledThread(true);
}
}
void ProcessState::spawnPooledThread(bool isMain) {
if (mThreadPoolStarted) {
String8 name = makeBinderThreadName();
ALOGV("Spawning new pooled thread, name=%s\n", name.string());
sp<Thread> t = new PoolThread(isMain);
t->run(name.string());
}
}
这里的Thread和Java不同,在这里线程run()启动后,调用的是threadLoop()方法,关于threadLoop()是如何被调用的(https://blog.csdn.net/ch853199769/article/details/79917188),ProcessState调用IPCThreadState->joinThreadPool(true)进一步处理。
//IPCThreadState.cpp
void IPCThreadState::joinThreadPool(bool isMain)
{
LOG_THREADPOOL("**** THREAD %p (PID %d) IS JOINING THE THREAD POOL\n", (void*)pthread_self(), getpid());
mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER);
status_t result;
do {
processPendingDerefs();
// now get the next command to be processed, waiting if necessary
result = getAndExecuteCommand();
if (result < NO_ERROR && result != TIMED_OUT && result != -ECONNREFUSED && result != -EBADF) {
LOG_ALWAYS_FATAL("getAndExecuteCommand(fd=%d) returned unexpected error %d, aborting",
mProcess->mDriverFD, result);
}
// Let this thread exit the thread pool if it is no longer
// needed and it is not the main process thread.
if(result == TIMED_OUT && !isMain) {
break;
}
} while (result != -ECONNREFUSED && result != -EBADF);
LOG_THREADPOOL("**** THREAD %p (PID %d) IS LEAVING THE THREAD POOL err=%d\n",
(void*)pthread_self(), getpid(), result);
mOut.writeInt32(BC_EXIT_LOOPER);
talkWithDriver(false);
}
可以看到还是通过循环等待消息,getAndExecuteCommand()通过talkWithDriver()访问“/dev/binder”节点,处理其他进程的通信消息,这样安卓应用程序就支持IPC(Binder进程间通信)了。
接下来看RuntimeInit.applicationInit()方法做了什么,其实就是找到参数类中的main方法,返回给一个Runnable执行:
//RuntimeInit.java
protected static Runnable findStaticMain(String className, String[] argv,
ClassLoader classLoader) {
.......
cl = Class.forName(className, true, classLoader);
m = cl.getMethod("main", new Class[] { String[].class });
return new MethodAndArgsCaller(m, argv);
}
static class MethodAndArgsCaller implements Runnable {
/** method to call */
private final Method mMethod;
/** argument array */
private final String[] mArgs;
public MethodAndArgsCaller(Method method, String[] args) {
mMethod = method;
mArgs = args;
}
public void run() {
try {
mMethod.invoke(null, new Object[] { mArgs });
} catch (IllegalAccessException ex) {
throw new RuntimeException(ex);
} catch (InvocationTargetException ex) {
Throwable cause = ex.getCause();
if (cause instanceof RuntimeException) {
throw (RuntimeException) cause;
} else if (cause instanceof Error) {
throw (Error) cause;
}
throw new RuntimeException(ex);
}
}
}
这个参数就是"android.app.ActivityThread"。
重点分析ActivityThread.main()函数:
// ActivityThread.java
public static void main(String[] args) {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");
// Install selective syscall interception
AndroidOs.install();
// CloseGuard defaults to true and can be quite spammy. We
// disable it here, but selectively enable it later (via
// StrictMode) on debug builds, but using DropBox, not logs.
CloseGuard.setEnabled(false);
Environment.initForCurrentUser();
// Make sure TrustedCertificateStore looks in the right place for CA certificates
final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
TrustedCertificateStore.setDefaultUserDirectory(configDir);
// Call per-process mainline module initialization.
initializeMainlineModules();
Process.setArgV0("" );
Looper.prepareMainLooper();
// Find the value for {@link #PROC_START_SEQ_IDENT} if provided on the command line.
// It will be in the format "seq=114"
long startSeq = 0;
if (args != null) {
for (int i = args.length - 1; i >= 0; --i) {
if (args[i] != null && args[i].startsWith(PROC_START_SEQ_IDENT)) {
startSeq = Long.parseLong(
args[i].substring(PROC_START_SEQ_IDENT.length()));
}
}
}
ActivityThread thread = new ActivityThread();
thread.attach(false, startSeq);
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
if (false) {
Looper.myLooper().setMessageLogging(new
LogPrinter(Log.DEBUG, "ActivityThread"));
}
// End of event ActivityThreadMain.
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
主要操作:
启动Looper开启消息循环机制,关于Looper可参考(https://blog.csdn.net/qq_36063677/article/details/129369042),这里重点关注操作 2.
因为main()函数是static静态的,先实例化ActivityThread对象,类变量mH在这时被初始化,用于驱动各个事件的Handler,类变量mAppThread也被初始化,它是ActivityThread的内部类ApplicationThread extends IApplicationThread.Stub,是一个binder对象,用于system_server进程和新的App进程通信管理:
@UnsupportedAppUsage
final ApplicationThread mAppThread = new ApplicationThread();
@UnsupportedAppUsage
final Looper mLooper = Looper.myLooper();
@UnsupportedAppUsage
final H mH = new H();
调用thread.attach():
private void attach(boolean system, long startSeq) {
//......
RuntimeInit.setApplicationObject(mAppThread.asBinder());
final IActivityManager mgr = ActivityManager.getService();
try {
mgr.attachApplication(mAppThread, startSeq);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
// Watch for getting close to heap limit.
BinderInternal.addGcWatcher(new Runnable() {
@Override public void run() {
if (!mSomeActivitiesChanged) {
return;
}
Runtime runtime = Runtime.getRuntime();
long dalvikMax = runtime.maxMemory();
long dalvikUsed = runtime.totalMemory() - runtime.freeMemory();
if (dalvikUsed > ((3*dalvikMax)/4)) {
if (DEBUG_MEMORY_TRIM) Slog.d(TAG, "Dalvik max=" + (dalvikMax/1024)
+ " total=" + (runtime.totalMemory()/1024)
+ " used=" + (dalvikUsed/1024));
mSomeActivitiesChanged = false;
try {
ActivityTaskManager.getService().releaseSomeActivities(mAppThread);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
}
});
}
mgr.attachApplication(mAppThread, startSeq);开始和AMS通信,BinderInternal.addGcWatcher()在内存大于3/4的时候告诉ActivityTaskManager释放内存。
attachApplication()后续调用attachApplicationLocked()执行下一步操作:
// ActivityManagerService.java
@GuardedBy("this")
private boolean attachApplicationLocked(@NonNull IApplicationThread thread,
int pid, int callingUid, long startSeq) {
ProcessRecord app;
app = mPidsSelfLocked.get(pid);
// App死亡回调
AppDeathRecipient adr = new AppDeathRecipient(
app, pid, thread);
thread.asBinder().linkToDeath(adr, 0);
// 告知App配置信息
thread.bindApplication(processName, appInfo, providerList, null, profilerInfo,
null, null, null, testMode,
mBinderTransactionTrackingEnabled, enableTrackAllocation,
isRestrictedBackupMode || !normalMode, app.isPersistent(),
new Configuration(app.getWindowProcessController().getConfiguration()),
app.compat, getCommonServicesLocked(app.isolated),
mCoreSettingsObserver.getCoreSettingsLocked(),
buildSerial, autofillOptions, contentCaptureOptions,
app.mDisabledCompatChanges);
// 将IApplicationThread关联到ProcessRecord,WindowProcessController
app.makeActive(thread, mProcessStats);
}
AMS先是通过pid拿到ProcessRecord对象,它保存着正在运行的进程的所有信息,在ProcessList->newProcessRecordLocked()方法中被实例化并返回,ProcessList->handleProcessStartedLocked()方法中调用mService.addPidLocked(app);添加到AMS的mPidsSelfLocked变量中管理。
@GuardedBy("mService")
final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
boolean isolated, int isolatedUid, HostingRecord hostingRecord) {
//......
final ProcessRecord r = new ProcessRecord(mService, info, proc, uid);
return r;
}
@GuardedBy("mService")
boolean handleProcessStartedLocked(ProcessRecord app, int pid, boolean usingWrapper,
long expectedStartSeq, boolean procAttached) {
//......
mService.addPidLocked(app);
return true;
}
成功获取到ProcessRecord对象后,注册app死亡回调,计算初始化一些app相关的配置信息,并通过IApplicationThread接口的bindApplication()通知给app端,关键的是app.makeActive()函数,它告诉system_server进程的ProcessRecord、WindowProcessController对象app进程已经启动了,可以通过IApplicationThread执行下一步操作,如执行Activity的生命周期方法,广播onReceive()等:
// ProcessRecord.java
class ProcessRecord implements WindowProcessListener {
IApplicationThread thread; // the actual proc... may be null only if
// 'persistent' is true (in which case we
// are in the process of launching the app)
public void makeActive(IApplicationThread _thread, ProcessStatsService tracker) {
//......
thread = _thread;
mWindowProcessController.setThread(thread);
}
}
// WindowProcessController.java
public class WindowProcessController extends ConfigurationContainer<ConfigurationContainer>
implements ConfigurationContainerListener {
// The actual proc... may be null only if 'persistent' is true (in which case we are in the
// process of launching the app)
private IApplicationThread mThread;
}
在makeActive()方法被调用前,ProcessRecord和WindowProcessController对象的IApplicationThread变量都为null,除非是persistent app,在被赋值后,system_server进程有了和app进程沟通的工具,可以回调Activity对象的onCreate(), onResume, onReceive()等:
// ActivityStackSupervisor.java
boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
boolean andResume, boolean checkConfig) throws RemoteException {
//......
// Create activity launch transaction.
final ClientTransaction clientTransaction = ClientTransaction.obtain(
proc.getThread(), r.appToken);
final DisplayContent dc = r.getDisplay().mDisplayContent;
clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
System.identityHashCode(r), r.info,
// TODO: Have this take the merged configuration instead of separate global
// and override configs.
mergedConfiguration.getGlobalConfiguration(),
mergedConfiguration.getOverrideConfiguration(), r.compat,
r.launchedFromPackage, task.voiceInteractor, proc.getReportedProcState(),
r.getSavedState(), r.getPersistentSavedState(), results, newIntents,
dc.isNextTransitionForward(), proc.createProfilerInfoIfNeeded(),
r.assistToken, r.createFixedRotationAdjustmentsIfNeeded()));
// Set desired final state.
final ActivityLifecycleItem lifecycleItem;
if (andResume) {
lifecycleItem = ResumeActivityItem.obtain(dc.isNextTransitionForward());
} else {
lifecycleItem = PauseActivityItem.obtain();
}
clientTransaction.setLifecycleStateRequest(lifecycleItem);
}
通过proc.getThread(), r.appToken参数构造ClientTransaction类对象,proc.getThread()就是WindowProcessController的mThread变量,判断当前的生命周期,LaunchActivityItem执行onCreate(),ResumeActivityItem执行onResume(),PauseActivityItem执行onPause(),那么这个事务ClientTransaction是怎么被执行的呢?接着往下看
proc.getThread()被赋值给ClientTransaction的mClient变量,ClientTransaction的执行方法schedule()就是通过mClient实现的:
// ClientTransaction.java
/** Target client. */
private IApplicationThread mClient;
public void schedule() throws RemoteException {
mClient.scheduleTransaction(this);
}
mClient就是system_server进程和app进程沟通的桥梁,从此就回到了app进程,回到ActivityThread查看进一步操作:
// ActivityThread.java
public final class ActivityThread extends ClientTransactionHandler {
private class ApplicationThread extends IApplicationThread.Stub {
@Override
public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
ActivityThread.this.scheduleTransaction(transaction);
}
}
}
// ClientTransactionHandler.java
public abstract class ClientTransactionHandler {
void scheduleTransaction(ClientTransaction transaction) {
transaction.preExecute(this);
sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
}
}
ActivityThread继承了ClientTransactionHandler,scheduleTransaction()方法是通过mH handler发送EXECUTE_TRANSACTION:
class H extends Handler {
public void handleMessage(Message msg) {
case EXECUTE_TRANSACTION:
final ClientTransaction transaction = (ClientTransaction) msg.obj;
mTransactionExecutor.execute(transaction);
if (isSystem()) {
// Client transactions inside system process are recycled on the client side
// instead of ClientLifecycleManager to avoid being cleared before this
// message is handled.
transaction.recycle();
}
// TODO(lifecycler): Recycle locally scheduled transactions.
break;
}
}
在EXECUTE_TRANSACTION消息被接收时处理了ClientTransaction事务,接下去就是执行生命周期方法了。
在IApplicationThread.aidl文件中定义了system_server进程和app进程的通信方法。