上篇写到App启动流程中,Launcher进程中点击LauncherActivity的图标启动发送startActivity的请求给SystemServer进程,SystemServer进程中ActivityTaskManagerService又通过socket进程通信方式,发送创建App进程的请求给Zygote进程,这篇接着上篇主要论述Zygote进程fork出App进程的后续流程。
Zygote进程fork出App进程后,会执行App进程中ActivityThread中的main方法。(关于这里可以参考Android应用进程的孵化)
public static void main(String[] args) {
........
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");
}
可以看到在ActivityThread的main方法中调用了ActivityThread的attach方法:
RuntimeInit.setApplicationObject(mAppThread.asBinder());
final IActivityManager mgr = ActivityManager.getService();
try {
//跨进程通信,通过Binder调用AMS的方法
//mAppThread:ApplicationThread,ActivityThread的内部类
mgr.attachApplication(mAppThread, startSeq);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
注意:这里通过Binder IPC 调用到了ActivityManagerService#attachApplication。
@Override
public final void attachApplication(IApplicationThread thread, long startSeq) {
if (thread == null) {
throw new SecurityException("Invalid application interface");
}
synchronized (this) {
int callingPid = Binder.getCallingPid();
final int callingUid = Binder.getCallingUid();
final long origId = Binder.clearCallingIdentity();
attachApplicationLocked(thread, callingPid, callingUid, startSeq);
Binder.restoreCallingIdentity(origId);
}
}
ActivityManagerService#attachApplication又调用了ActivityManagerService#attachApplicationLocked():
private boolean attachApplicationLocked(@NonNull IApplicationThread thread,
int pid, int callingUid, long startSeq) {
.......
final ProviderInfoList providerList = ProviderInfoList.fromList(providers);
if (app.getIsolatedEntryPoint() != null) {
// This is an isolated process which should just call an entry point instead of
// being bound to an application.
thread.runIsolatedEntryPoint(
app.getIsolatedEntryPoint(), app.getIsolatedEntryPointArgs());
} else if (instr2 != null) {
thread.bindApplication(processName, appInfo,
app.sdkSandboxClientAppVolumeUuid, app.sdkSandboxClientAppPackage,
providerList,
instr2.mClass,
profilerInfo, instr2.mArguments,
instr2.mWatcher,
instr2.mUiAutomationConnection, testMode,
mBinderTransactionTrackingEnabled, enableTrackAllocation,
isRestrictedBackupMode || !normalMode, app.isPersistent(),
new Configuration(app.getWindowProcessController().getConfiguration()),
app.getCompat(), getCommonServicesLocked(app.isolated),
mCoreSettingsObserver.getCoreSettingsLocked(),
buildSerial, autofillOptions, contentCaptureOptions,
app.getDisabledCompatChanges(), serializedSystemFontMap,
app.getStartElapsedTime(), app.getStartUptime());
} else {
thread.bindApplication(processName, appInfo,
app.sdkSandboxClientAppVolumeUuid, app.sdkSandboxClientAppPackage,
providerList, null, profilerInfo, null, null, null, testMode,
mBinderTransactionTrackingEnabled, enableTrackAllocation,
isRestrictedBackupMode || !normalMode, app.isPersistent(),
new Configuration(app.getWindowProcessController().getConfiguration()),
app.getCompat(), getCommonServicesLocked(app.isolated),
mCoreSettingsObserver.getCoreSettingsLocked(),
buildSerial, autofillOptions, contentCaptureOptions,
app.getDisabledCompatChanges(), serializedSystemFontMap,
app.getStartElapsedTime(), app.getStartUptime());
}
.....
} catch (Exception e) {
.....
return false;
}
......
// See if the top visible activity is waiting to run in this process...
if (normalMode) {
try {
didSomething = mAtmInternal.attachApplication(app.getWindowProcessController());
} catch (Exception e) {
Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
badApp = true;
}
}
......
return true;
}
注意,在ActivityManagerService#attachApplicationLocked()方法中,有两段重要的代码。
第1段是:
thread.bindApplication(processName, appInfo,
app.sdkSandboxClientAppVolumeUuid, app.sdkSandboxClientAppPackage,
providerList,
instr2.mClass,
profilerInfo, instr2.mArguments,
instr2.mWatcher,
instr2.mUiAutomationConnection, testMode,
mBinderTransactionTrackingEnabled, enableTrackAllocation,
isRestrictedBackupMode || !normalMode, app.isPersistent(),
new Configuration(app.getWindowProcessController().getConfiguration()),
app.getCompat(), getCommonServicesLocked(app.isolated),
mCoreSettingsObserver.getCoreSettingsLocked(),
buildSerial, autofillOptions, contentCaptureOptions,
app.getDisabledCompatChanges(), serializedSystemFontMap,
app.getStartElapsedTime(), app.getStartUptime());
第2段是:
mAtmInternal.attachApplication(app.getWindowProcessController());
这两段最终分别对应Application的创建和App进程中首个Activity的创建。
(1)先看thread.bindApplicaiton,这里的thread 是 IApplicationThread,通过Binder IPC,调用到App进程中ActivityThread的内部类ApplicationThread的bindApplication方法:
@Override
public final void bindApplication(String processName, ApplicationInfo appInfo,
String sdkSandboxClientAppVolumeUuid, String sdkSandboxClientAppPackage,
ProviderInfoList providerList, ComponentName instrumentationName,
ProfilerInfo profilerInfo, Bundle instrumentationArgs,
IInstrumentationWatcher instrumentationWatcher,
IUiAutomationConnection instrumentationUiConnection, int debugMode,
boolean enableBinderTracking, boolean trackAllocation,
boolean isRestrictedBackupMode, boolean persistent, Configuration config,
CompatibilityInfo compatInfo, Map services, Bundle coreSettings,
String buildSerial, AutofillOptions autofillOptions,
ContentCaptureOptions contentCaptureOptions, long[] disabledCompatChanges,
SharedMemory serializedSystemFontMap,
long startRequestedElapsedTime, long startRequestedUptime) {
......
AppBindData data = new AppBindData();
data.processName = processName;
data.appInfo = appInfo;
data.sdkSandboxClientAppVolumeUuid = sdkSandboxClientAppVolumeUuid;
data.sdkSandboxClientAppPackage = sdkSandboxClientAppPackage;
data.providers = providerList.getList();
data.instrumentationName = instrumentationName;
data.instrumentationArgs = instrumentationArgs;
data.instrumentationWatcher = instrumentationWatcher;
data.instrumentationUiAutomationConnection = instrumentationUiConnection;
data.debugMode = debugMode;
data.enableBinderTracking = enableBinderTracking;
data.trackAllocation = trackAllocation;
data.restrictedBackupMode = isRestrictedBackupMode;
data.persistent = persistent;
data.config = config;
data.compatInfo = compatInfo;
data.initProfilerInfo = profilerInfo;
data.buildSerial = buildSerial;
data.autofillOptions = autofillOptions;
data.contentCaptureOptions = contentCaptureOptions;
data.disabledCompatChanges = disabledCompatChanges;
data.mSerializedSystemFontMap = serializedSystemFontMap;
data.startRequestedElapsedTime = startRequestedElapsedTime;
data.startRequestedUptime = startRequestedUptime;
sendMessage(H.BIND_APPLICATION, data);
}
可以看到在ApplicationThread的bindApplicaiton方法中,最终发送了tag为H.BIND_APPLICATION的Handler消息到主线程(ActivityThread所在的线程)。再看下接收到消息之后是怎么处理的?
public void handleMessage(Message msg) {
if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
switch (msg.what) {
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;
.....
}
}
可以看到ActivityThread在接收到H.BIND_APPLICATION的Handler消息后,调用了ActivityThread的handleBindApplication方法,我们来看一下这个方法:
private void handleBindApplication(AppBindData data) {
.......
if (ii != null) {
initInstrumentation(ii, data, appContext);
} else {
mInstrumentation = new Instrumentation();
mInstrumentation.basicInit(this);
}
....
Application app;
final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskWrites();
final StrictMode.ThreadPolicy writesAllowedPolicy = StrictMode.getThreadPolicy();
try {
// If the app is being launched for full backup or restore, bring it up in
// a restricted environment with the base application class.
app = data.info.makeApplicationInner(data.restrictedBackupMode, null);
....
// Do this after providers, since instrumentation tests generally start their
// test thread at this point, and we don't want that racing.
try {
mInstrumentation.onCreate(data.instrumentationArgs);
}
catch (Exception e) {
throw new RuntimeException(
"Exception thrown in onCreate() of "
+ data.instrumentationName + ": " + e.toString(), e);
}
try {
mInstrumentation.callApplicationOnCreate(app);
} catch (Exception e) {
if (!mInstrumentation.onException(app, e)) {
throw new RuntimeException(
"Unable to create application " + app.getClass().getName()
+ ": " + e.toString(), e);
}
}
} finally {
.....
}
}
这个方法比较长,我们来看其中比较重要的几行代码,首先看下:
data.info.makeApplicationInner(data.restrictedBackupMode, null);
这里的data.info 是LoadedApk的对象,调用的是LoadedApk.makeApplication():
public Application makeApplicationInner(boolean forceDefaultAppClass,
Instrumentation instrumentation) {
return makeApplicationInner(forceDefaultAppClass, instrumentation,
/* allowDuplicateInstances= */ false);
}
private Application makeApplicationInner(boolean forceDefaultAppClass,
Instrumentation instrumentation, boolean allowDuplicateInstances) {
if (mApplication != null) {
return mApplication;
}
.....
Application app = null;
final String myProcessName = Process.myProcessName();
String appClass = mApplicationInfo.getCustomApplicationClassNameForProcess(
myProcessName);
if (forceDefaultAppClass || (appClass == null)) {
appClass = "android.app.Application";
}
try {
final java.lang.ClassLoader cl = getClassLoader();
....
app = mActivityThread.mInstrumentation.newApplication(
cl, appClass, appContext);
appContext.setOuterContext(app);
} catch (Exception e) {
if (!mActivityThread.mInstrumentation.onException(app, e)) {
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
throw new RuntimeException(
"Unable to instantiate application " + appClass
+ " package " + mPackageName + ": " + e.toString(), e);
}
}
......
if (instrumentation != null) {
try {
instrumentation.callApplicationOnCreate(app);
} catch (Exception e) {
if (!instrumentation.onException(app, e)) {
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
throw new RuntimeException(
"Unable to create application " + app.getClass().getName()
+ ": " + e.toString(), e);
}
}
}
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
return app;
}
这里主要关注一下这行代码:
mActivityThread.mInstrumentation.newApplication(cl, appClass, appContext);
这又调用到了ActivityThread中Instrumentation对象的newApplicaiton方法,这里需要注意的一点是,一个进程中只会创建一个Instrumentation对象,而这个对象又会被每一个Activity所持有。
Instrumentation#newApplicaiton:
Application app = getFactory(context.getPackageName()).instantiateApplication(cl, className);
app.attach(context);
Application.attach():
final void attach(Context context) {
attachBaseContext(context);
mLoadedApk = ContextImpl.getImpl(context).mPackageInfo;
}
再次回到ActivityThread的handleBindApplication方法中,看到有调用Instrumentation.callApplicationOnCreate():
public void callApplicationOnCreate(Application app) {
app.onCreate(); //Application.onCreate()
}
至此,Applicaiton创建完毕。
(2)再看上面提到的 mAtmInternal.attachApplication(app.getWindowProcessController());
这里的mAtmInternal在ActivityManagerService的构造方法中有赋值:
mAtmInternal = LocalServices.getService(ActivityTaskManagerInternal.class);
而ActivityTaskManagerInternal是个抽象类,通过LocalServices.getService(ActivityTaskManagerInternal.class);可以获取到ActivityTaskManagerInternal的子类 ActivityTaskManagerService$LocalService的对象:
final class LocalService extends ActivityTaskManagerInternal {
}
所以上面的 mAtmInternal.attachApplication(app.getWindowProcessController()); 其实调用的是ActivityTaskManagerService$LocalService#attachApplication方法:
@Override
public boolean attachApplication(WindowProcessController wpc) throws RemoteException {
synchronized (mGlobalLockWithoutBoost) {
if (Trace.isTagEnabled(TRACE_TAG_WINDOW_MANAGER)) {
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "attachApplication:" + wpc.mName);
}
try {
return mRootWindowContainer.attachApplication(wpc);
} finally {
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
}
}
}
可以看到这里调用了RootWindowContainer.attach()方法,紧接着RootWindowContainer.attach()–>RootWindowContainer.startActivityForAttachedApplicationIfNeeded()–>ActivityStackSupervisor.realStartActivityLocked()(APP进程创建后直接调用此方法,见方法ActivityStackSupervisor.startSpecificActivity)
ActivityStackSupervisor.realStartActivityLocked():
// Create activity launch transaction.
//初始化ClientTransaction.mClient=proc.getThread()=IApplicationThread
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);
// Schedule transaction.
//ClientLifecycleManager.scheduleTransaction()
mService.getLifecycleManager().scheduleTransaction(clientTransaction);
在ActivityStackSupervisor.realStartActivityLocked()中调用了ClientLifecycleManager.scheduleTransaction()方法:
final IApplicationThread client = transaction.getClient();
//mClient.scheduleTransaction(this)-->ApplicationThread.scheduleTransaction()
//ApplicationThread是ActivityThread的内部类
transaction.schedule();
这里通过Binder IPC又调用了App进程中ApplicationThread的scheduleTransaction方法:
@Override
public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
//ActivityThread extends ClientTransactionHandler
ActivityThread.this.scheduleTransaction(transaction);
}
而ActivityThread的父类是ClientTransactionHandler,这里实际调用的是ClientTransactionHandler中的scheduleTransaction方法:
void scheduleTransaction(ClientTransaction transaction) {
transaction.preExecute(this);
sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
}
可以看到scheduleTransaction方法里面发送了H.EXECUTE_TRANSACTION的Handler消息到主线程ActivitThread中,在ActivityThread中接收到H.EXECUTE_TRANSACTION消息后的处理:
public void handleMessage(Message msg) {
switch (msg.what) {
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;
}
可以看到这里调用了TransactionExecutor.execute(transaction):
//-->Activity.onCreate()
executeCallbacks(transaction);
executeLifecycleState(transaction);
TransactionExecutor.executeCallbacks(transaction):
public void executeCallbacks(ClientTransaction transaction) {
final List<ClientTransactionItem> callbacks = transaction.getCallbacks();
if (callbacks == null || callbacks.isEmpty()) {
// No callbacks to execute, return early.
return;
}
final int size = callbacks.size();
for (int i = 0; i < size; ++i) {
//LaunchActivityItem.obtain() = LaunchActivityItem
final ClientTransactionItem item = callbacks.get(i);
if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "Resolving callback: " + item);
final int postExecutionState = item.getPostExecutionState();
final int closestPreExecutionState = mHelper.getClosestPreExecutionState(r,item.getPostExecutionState());
if (closestPreExecutionState != UNDEFINED) {
cycleToPath(r, closestPreExecutionState, transaction);
}
item.execute(mTransactionHandler, token, mPendingActions);
item.postExecute(mTransactionHandler, token, mPendingActions);
if (r == null) {
// Launch activity request will create an activity record.
r = mTransactionHandler.getActivityClient(token);
}
}
}
在TransactionExecutor.executeCallbacks(transaction)中又调用了LaunchActivityItem.execute()方法:
//client = ActivityThread
public void execute(ClientTransactionHandler client, IBinder token,PendingTransactionActions pendingActions) {
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
ActivityClientRecord r = new ActivityClientRecord(token, mIntent, mIdent, mInfo,
mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mState, mPersistentState,
mPendingResults, mPendingNewIntents, mIsForward,
mProfilerInfo, client, mAssistToken, mFixedRotationAdjustments);
//ActivityThread.handleLaunchActivity()-->performLaunchActivity()
client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
可以看到这里又调用了ActivityThread的handleLaunchActivity:
//创建Activity的context
ContextImpl appContext = createBaseContextForActivity(r);
Activity activity = null;
try {
java.lang.ClassLoader cl = appContext.getClassLoader();
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
StrictMode.incrementExpectedActivityCount(activity.getClass());
r.intent.setExtrasClassLoader(cl);
r.intent.prepareToEnterProcess();
if (r.state != null) {
r.state.setClassLoader(cl);
}
} catch (Exception e) {
if (!mInstrumentation.onException(activity, e)) {
throw new RuntimeException(
"Unable to instantiate activity " + component
+ ": " + e.toString(), e);
}
}
//创建PhoneWindow及WindowManager
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, window, r.configCallback,r.assistToken);
if (r.isPersistable()) {
//Activity.onCreate()
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
可以看到在ActivityThread的handleLaunchActivity中又调用了Instrumentation的newActivity方法:
public Activity newActivity(ClassLoader cl, String className,
Intent intent)
throws InstantiationException, IllegalAccessException,
ClassNotFoundException {
String pkg = intent != null && intent.getComponent() != null
? intent.getComponent().getPackageName() : null;
return getFactory(pkg).instantiateActivity(cl, className, intent);
}
AppComponentFactory#instaniateActivity:
public @NonNull Activity instantiateActivity(@NonNull ClassLoader cl, @NonNull String className,
@Nullable Intent intent)
throws InstantiationException, IllegalAccessException, ClassNotFoundException {
return (Activity) cl.loadClass(className).newInstance();
}
这里通过Class.newInstance()的方式创建了Activity对象。
再回到上面ActivityThread的handleLaunchActivity,在调用mInstrumentation.newActivity(
cl, component.getClassName(), r.intent); 之后,又调用了activity的attatch方法以及Instrumentation的callActivityOnCreate方法:
public void callActivityOnCreate(Activity activity, Bundle icicle) {
prePerformCreate(activity);
activity.performCreate(icicle);
postPerformCreate(activity);
}
这里重点关注下activity.performCreate(icicle);
看下Activity的performCreate方法:
final void performCreate(Bundle icicle, PersistableBundle persistentState) {
if (Trace.isTagEnabled(Trace.TRACE_TAG_WINDOW_MANAGER)) {
Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "performCreate:"
+ mComponent.getClassName());
}
dispatchActivityPreCreated(icicle);
mCanEnterPictureInPicture = true;
// initialize mIsInMultiWindowMode and mIsInPictureInPictureMode before onCreate
final int windowingMode = getResources().getConfiguration().windowConfiguration
.getWindowingMode();
mIsInMultiWindowMode = inMultiWindowMode(windowingMode);
mIsInPictureInPictureMode = windowingMode == WINDOWING_MODE_PINNED;
mShouldDockBigOverlays = getResources().getBoolean(R.bool.config_dockBigOverlayWindows);
restoreHasCurrentPermissionRequest(icicle);
if (persistentState != null) {
onCreate(icicle, persistentState);
} else {
onCreate(icicle);
}
EventLogTags.writeWmOnCreateCalled(mIdent, getComponentName().getClassName(),
"performCreate");
mActivityTransitionState.readState(icicle);
mVisibleFromClient = !mWindow.getWindowStyle().getBoolean(
com.android.internal.R.styleable.Window_windowNoDisplay, false);
mFragments.dispatchActivityCreated();
mActivityTransitionState.setEnterActivityOptions(this, getActivityOptions());
dispatchActivityPostCreated(icicle);
Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
}
可以看到在Activity的performCreate方法中,又调用了Activity的onCreate方法,至此Activity创建流程结束。
总结
- AMS启动一个进程其实是打开这个App的首页面,当发现这个首页所在的进程不存在时,则会发送socket消息给Zygote进程。Zygote进程中的ZygoteServer在接收到这条socket消息后,通过fork去创建出app的进程。
- Zygote进程中的ZygoteServer里面有个死循环,不停的轮询有没有发送过来的socket消息,当有消息发送过来时,就会去解析这条socket消息中的参数,然后通过fork()出一个新进程。如果pid==0,即当前处于子进程;如果pid>0,即处于父进程。fork()采用copy-on-write机制,有些类如果不做改变,甚至都不用复制,子进程和父进程可以共享这部分数据,从而省去不少的内存占用。