接着上篇:https://www.jianshu.com/p/feb857e0bb56?v=1678258277972
进入AMS,请求创建应用进程
这里直接看startProcess。
//ActivityManagerService.java:
public final class LocalService extends ActivityManagerInternal
implements ActivityManagerLocal {
@Override
public void startProcess(String processName, ApplicationInfo info,
boolean knownToBeDead, String hostingType, ComponentName hostingName) {
try {
if (Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "startProcess:"
+ processName);
}
synchronized (ActivityManagerService.this) {
//调用到ActivityManagerService中的startProcessLocked方法
startProcessLocked(processName, info, knownToBeDead, 0 /* intentFlags */,
new HostingRecord(hostingType, hostingName),
false /* allowWhileBooting */, false /* isolated */,
true /* keepIfLarge */);
}
} finally {
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
}
}
}
//AMS的startProcessLocked方法
@GuardedBy("this")
final ProcessRecord startProcessLocked(String processName,
ApplicationInfo info, boolean knownToBeDead, int intentFlags,
HostingRecord hostingRecord, boolean allowWhileBooting,
boolean isolated, boolean keepIfLarge) {
return mProcessList.startProcessLocked(processName, info, knownToBeDead, intentFlags,
hostingRecord, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
null /* crashHandler */);
}
很清晰,AMS内部类LocalService的startProcess()调用了startProcessLocked(),而startProcessLocked()又调用了ProcessList的startProcessLocked()。
//ProcessList.java:
@GuardedBy("mService")
final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
boolean knownToBeDead, int intentFlags, HostingRecord hostingRecord,
boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
ProcessRecord app;
if (!isolated) {
app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
......
} else {
......
}
......
final boolean success = startProcessLocked(app, hostingRecord, abiOverride);
return success ? app : null;
}
@GuardedBy("mService")
final boolean startProcessLocked(ProcessRecord app, HostingRecord hostingRecord,
String abiOverride) {
return startProcessLocked(app, hostingRecord,
false /* disableHiddenApiChecks */, false /* mountExtStorageFull */, abiOverride);
}
@GuardedBy("mService")
boolean startProcessLocked(ProcessRecord app, HostingRecord hostingRecord,
boolean disableHiddenApiChecks, boolean mountExtStorageFull,
String abiOverride) {
......
try {
......
if ("1".equals(SystemProperties.get("debug.checkjni"))) {
runtimeFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
}
......
final String seInfo = app.info.seInfo
+ (TextUtils.isEmpty(app.info.seInfoUser) ? "" : app.info.seInfoUser);
// Start the process. It will either succeed and return a result containing
// the PID of the new process, or else throw a RuntimeException.
final String entryPoint = "android.app.ActivityThread";
return startProcessLocked(hostingRecord, entryPoint, app, uid, gids,
runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet, invokeWith,
startTime);
} catch (RuntimeException e) {
......
}
}
@GuardedBy("mService")
boolean startProcessLocked(HostingRecord hostingRecord,
String entryPoint,
ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
String seInfo, String requiredAbi, String instructionSet, String invokeWith,
long startTime) {
app.pendingStart = true;
app.killedByAm = false;
app.removed = false;
app.killed = false;
......
if (mService.mConstants.FLAG_PROCESS_START_ASYNC) {
mService.mProcStartHandler.post(() -> {
try {
final Process.ProcessStartResult startResult = startProcess(app.hostingRecord,
entryPoint, app, app.startUid, gids, runtimeFlags, mountExternal,
app.seInfo, requiredAbi, instructionSet, invokeWith, app.startTime);
synchronized (mService) {
handleProcessStartedLocked(app, startResult, startSeq);
}
} catch (RuntimeException e) {
......
}
});
return true;
} else {
try {
final Process.ProcessStartResult startResult = startProcess(hostingRecord,
entryPoint, app,
uid, gids, runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet,
invokeWith, startTime);
handleProcessStartedLocked(app, startResult.pid, startResult.usingWrapper,
startSeq, false);
} catch (RuntimeException e) {
......
}
return app.pid > 0;
}
}
从上面可以看到,经过了多次同名方法 startProcessLocked() 调用,在调用过程创建了ProcessRecord对象并处理保存了进程所需的各种信息。
最终调用的是startProcess()。
//ProcessList.java:
private Process.ProcessStartResult startProcess(HostingRecord hostingRecord, String entryPoint,
ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
String seInfo, String requiredAbi, String instructionSet, String invokeWith,
long startTime) {
try {
checkSlow(startTime, "startProcess: asking zygote to start proc");
final Process.ProcessStartResult startResult;
if (hostingRecord.usesWebviewZygote()) {
startResult = startWebView(entryPoint,
......
} else if (hostingRecord.usesAppZygote()) {
final AppZygote appZygote = createAppZygoteForProcessIfNeeded(app);
startResult = appZygote.getProcess().start(entryPoint,
......
} else {
startResult = Process.start(entryPoint,
app.processName, uid, uid, gids, runtimeFlags, mountExternal,
app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
app.info.dataDir, invokeWith, app.info.packageName,
new String[] {PROC_START_SEQ_IDENT + app.startSeq});
}
checkSlow(startTime, "startProcess: returned from zygote!");
return startResult;
} finally {
......
}
}
这里的hostingRecord是在startProcess()调用时传入的参数new HostingRecord(hostingType, hostingName),跟踪可以看到其mHostingZygote=REGULAR_ZYGOTE。所以走的Process.start()。
Zygote创建应用进程
//Process.java:
public static final ZygoteProcess ZYGOTE_PROCESS = new ZygoteProcess();
public static ProcessStartResult start(@NonNull final String processClass,
@Nullable final String niceName,
int uid, int gid, @Nullable int[] gids,
int runtimeFlags,
int mountExternal,
int targetSdkVersion,
@Nullable String seInfo,
@NonNull String abi,
@Nullable String instructionSet,
@Nullable String appDataDir,
@Nullable String invokeWith,
@Nullable String packageName,
@Nullable String[] zygoteArgs) {
return ZYGOTE_PROCESS.start(processClass, niceName, uid, gid, gids,
runtimeFlags, mountExternal, targetSdkVersion, seInfo,
abi, instructionSet, appDataDir, invokeWith, packageName,
/*useUsapPool=*/ true, zygoteArgs);
}
ZYGOTE_PROCESS是新建的ZygoteProcess对象,在不带参数构造中定义了4中socket的地址。这里直接看ZygoteProcess.start()。
//ZygoteProcess.java:
public final Process.ProcessStartResult start(@NonNull final String processClass,
......) {
......
try {
return startViaZygote(processClass, niceName, uid, gid, gids,
runtimeFlags, mountExternal, targetSdkVersion, seInfo,
abi, instructionSet, appDataDir, invokeWith, /*startChildZygote=*/ false,
packageName, useUsapPool, zygoteArgs);
} catch (ZygoteStartFailedEx ex) {
}
}
private Process.ProcessStartResult startViaZygote(@NonNull final String processClass,
......)
throws ZygoteStartFailedEx {
ArrayList<String> argsForZygote = new ArrayList<>();
// --runtime-args, --setuid=, --setgid=,
// and --setgroups= must go first
argsForZygote.add("--runtime-args");
argsForZygote.add("--setuid=" + uid);
argsForZygote.add("--setgid=" + gid);
argsForZygote.add("--runtime-flags=" + runtimeFlags);
if (mountExternal == Zygote.MOUNT_EXTERNAL_DEFAULT) {
argsForZygote.add("--mount-external-default");
}
......
synchronized(mLock) {
// The USAP pool can not be used if the application will not use the systems graphics
// driver. If that driver is requested use the Zygote application start path.
return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi),
useUsapPool,
argsForZygote);
}
}
ZygoteProcess.start()调用了startViaZygote,argsForZygote保存了启动的应用进程的完整参数。最后调用zygoteSendArgsAndGetResult()发送参数 通过socket进行通信,完成应用进程的fork,并获取结果Process.ProcessStartResult。
这里主要看下 openZygoteSocketIfNeeded(),这个是打开Zygote socket的过程。
//ZygoteProcess.java:
@GuardedBy("mLock")
private ZygoteState openZygoteSocketIfNeeded(String abi) throws ZygoteStartFailedEx {
try {
attemptConnectionToPrimaryZygote();
if (primaryZygoteState.matches(abi)) {
return primaryZygoteState;
}
if (mZygoteSecondarySocketAddress != null) {
// The primary zygote didn't match. Try the secondary.
attemptConnectionToSecondaryZygote();
if (secondaryZygoteState.matches(abi)) {
return secondaryZygoteState;
}
}
} catch (IOException ioe) {
}
}
@GuardedBy("mLock")
private void attemptConnectionToPrimaryZygote() throws IOException {
if (primaryZygoteState == null || primaryZygoteState.isClosed()) {
primaryZygoteState =
ZygoteState.connect(mZygoteSocketAddress, mUsapPoolSocketAddress);
maybeSetApiBlacklistExemptions(primaryZygoteState, false);
maybeSetHiddenApiAccessLogSampleRate(primaryZygoteState);
maybeSetHiddenApiAccessStatslogSampleRate(primaryZygoteState);
}
}
private static class ZygoteState implements AutoCloseable {
static ZygoteState connect(@NonNull LocalSocketAddress zygoteSocketAddress,
@Nullable LocalSocketAddress usapSocketAddress)
throws IOException {
......
final LocalSocket zygoteSessionSocket = new LocalSocket();
.......
try {
zygoteSessionSocket.connect(zygoteSocketAddress);
zygoteInputStream = new DataInputStream(zygoteSessionSocket.getInputStream());
zygoteOutputWriter =
new BufferedWriter(
new OutputStreamWriter(zygoteSessionSocket.getOutputStream()),
Zygote.SOCKET_BUFFER_SIZE);
} catch (IOException ex) {
......
}
return new ZygoteState(zygoteSocketAddress, usapSocketAddress,
zygoteSessionSocket, zygoteInputStream, zygoteOutputWriter,
getAbiList(zygoteOutputWriter, zygoteInputStream));
}
}
openZygoteSocketIfNeeded()返回一个 ZygoteState,这个是ZygoteProcess类的内部类,是保存与zygote进程进行通信时的状态信息。
attemptConnectionToPrimaryZygote()和attemptConnectionToSecondaryZygote()类似。通过connect()打开socket并通过ZygoteState保存状态信息。
关于进入connect()后通过socket与zygote进程通信fork出应用进程的过程 个人也需进一步查看学习 在这里不说了。
应用进程主线程-执行ActivityThread的main()
当应用进程fork出来后,最终会执行到ActivityThread的main()方法。关于应用进程相关的略过,这里主要是应用进程。
//ActivityThread.java:
public static void main(String[] args) {
// 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);
Process.setArgV0("<pre-initialized>");
Looper.prepareMainLooper();
......
ActivityThread thread = new ActivityThread();
thread.attach(false, startSeq);
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
......
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
这里很多熟悉的地方:
主线程默认创建的Looper,且不可退出。在 Android消息机制(Handler)详述 详细说过。
创建了ActivityThread对象,执行了attach(),attach()中这里第一个参数是false,即非系统进程。AMS源码解析https://www.jianshu.com/p/a3be43238458 则是true,是系统进程。
下面直接看下ActivityThread.attach()。
注:此时activity还未创建,activity的attach()还在后面。
@UnsupportedAppUsage
//ActivityThread.java:
private void attach(boolean system, long startSeq) {
sCurrentActivityThread = this;
mSystemThread = system;
if (!system) {
android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",
UserHandle.myUserId());
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();
}
}
}
});
} else {
......
}
......
}
主要来看下mgr.attachApplication()。很明显这个也是binder机制进行跨进程的,调用的是AMS的attachApplication()。
进入系统进程,将应用进程绑定到ATMS中
//ActivityManagerService.java:
@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);
}
}
@GuardedBy("this")
private boolean attachApplicationLocked(@NonNull IApplicationThread thread,
int pid, int callingUid, long startSeq) {
// Find the application record that is being attached... either via
// the pid if we are running in multiple processes, or just pull the
// next app record if we are emulating process with anonymous threads.
ProcessRecord app;
long startTime = SystemClock.uptimeMillis();
long bindApplicationTimeMillis;
if (pid != MY_PID && pid >= 0) {
synchronized (mPidsSelfLocked) {
app = mPidsSelfLocked.get(pid);
}
......
final String processName = app.processName;
......
final BackupRecord backupTarget = mBackupTargets.get(app.userId);
try {
......
mAtmInternal.preBindApplication(app.getWindowProcessController());
final ActiveInstrumentation instr2 = app.getActiveInstrumentation();
if (app.isolatedEntryPoint != null) {
// This is an isolated process which should just call an entry point instead of
// being bound to an application.
thread.runIsolatedEntryPoint(app.isolatedEntryPoint, app.isolatedEntryPointArgs);
} else if (instr2 != null) {
thread.bindApplication(processName, appInfo, providers,
instr2.mClass,
profilerInfo, instr2.mArguments,
instr2.mWatcher,
instr2.mUiAutomationConnection, testMode,
mBinderTransactionTrackingEnabled, enableTrackAllocation,
isRestrictedBackupMode || !normalMode, app.isPersistent(),
new Configuration(app.getWindowProcessController().getConfiguration()),
app.compat, getCommonServicesLocked(app.isolated),
mCoreSettingsObserver.getCoreSettingsLocked(),
buildSerial, autofillOptions, contentCaptureOptions);
} else {
thread.bindApplication(processName, appInfo, providers, 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);
}
.......
} catch (Exception e) {
......
// 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;
}
attachApplication()->attachApplicationLocked(),主要看下thread.bindApplication()和mAtmInternal.attachApplication()。
thread.bindApplication()实际调用的是 ApplicationThread下的 bindApplication()。ApplicationThread是ActivityThread的内部类,private class ApplicationThread extends IApplicationThread.Stub。注意当前是在AMS进程,其中的thread是传入的 是应用进程主线程。
mAtmInternal.attachApplication()最终调用的是ATMS中的 attachApplication()。
先来看下thread.bindApplication()
//ActivityThread.java->ApplicationThread class:
public final void bindApplication(String processName, ApplicationInfo appInfo,
......) {
......
data.contentCaptureOptions = contentCaptureOptions;
sendMessage(H.BIND_APPLICATION, data);
}
//ActivityThread.java->H class:
class H extends Handler {
public static final int BIND_APPLICATION = 110;
public void handleMessage(Message msg) {
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.java:
private void handleBindApplication(AppBindData data) {
......
data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
......
// Continue loading instrumentation.
if (ii != null) {
......
try {
final ClassLoader cl = instrContext.getClassLoader();
mInstrumentation = (Instrumentation)
cl.loadClass(data.instrumentationName.getClassName()).newInstance();
......
}
......
// Allow disk access during application and provider setup. This could
// block processing ordered broadcasts, but later processing would
// probably end up doing the same disk access.
Application app;
try {
app = data.info.makeApplication(data.restrictedBackupMode, null);
......
try {
mInstrumentation.callApplicationOnCreate(app);
} catch (Exception e) {
......
}
}
......
}
public final LoadedApk getPackageInfoNoCheck(ApplicationInfo ai,
CompatibilityInfo compatInfo) {
return getPackageInfo(ai, compatInfo, null, false, true, false);
}
//Application.java:
/**
* Called when the application is starting, before any activity, service,
* or receiver objects (excluding content providers) have been created.
*/
@CallSuper
public void onCreate() {
}
这时ApplicationThread和ActivityThread在同一进程中,所以bindApplication()通过handler通信,发送message(BIND_APPLICATION),直接看到处理部分handleBindApplication()。
通过 cl.loadClass(data.instrumentationName.getClassName()).newInstance()
反射创建了Instrumentation对象。
通过 getPackageInfoNoCheck()
创建LoadedApk对象并保存在data.info。代码流程:getPackageInfoNoCheck()->getPackageInfo()->new LoadedApk()
,都在ActivityThread中。
通过data.info.makeApplication(data.restrictedBackupMode, null)
创建了Application。关键代码看下面。
最后通过mInstrumentation.callApplicationOnCreate(app)
调用了app.onCreate();
,Application创建完成。
这些操作是thread下的,前面说过是传入的 应用进程主线程。所以创建Application是在应用进程中的。
//LoadedApk.java:
@UnsupportedAppUsage
public Application makeApplication(boolean forceDefaultAppClass,
Instrumentation instrumentation) {
Application app = null;
String appClass = mApplicationInfo.className;
try {
java.lang.ClassLoader cl = getClassLoader();
......
ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
app = mActivityThread.mInstrumentation.newApplication(
cl, appClass, appContext);
appContext.setOuterContext(app);
} catch (Exception e) {
}
mActivityThread.mAllApplications.add(app);
mApplication = app;
return app;
}
//Instrumentation.java:
public Application newApplication(ClassLoader cl, String className, Context context)
throws InstantiationException, IllegalAccessException,
ClassNotFoundException {
Application app = getFactory(context.getPackageName())
.instantiateApplication(cl, className);
app.attach(context);
return app;
}
private AppComponentFactory getFactory(String pkg) {
......
return apk.getAppFactory();
}
//AppComponentFactory.java:
public @NonNull Application instantiateApplication(@NonNull ClassLoader cl,
@NonNull String className)
throws InstantiationException, IllegalAccessException, ClassNotFoundException {
return (Application) cl.loadClass(className).newInstance();
}
//Application.java:
/* package */ final void attach(Context context) {
attachBaseContext(context);
mLoadedApk = ContextImpl.getImpl(context).mPackageInfo;
}
//
这就是makeApplication()方法创建Application的过程。注意 makeApplication()传入的instrumentation为null,Application的实例化也是通过反射。
接着看第二点mAtmInternal.attachApplication()
//ActivityTaskManagerService.java:
@HotPath(caller = HotPath.PROCESS_CHANGE)
@Override
public boolean attachApplication(WindowProcessController wpc) throws RemoteException {
synchronized (mGlobalLockWithoutBoost) {
return mRootActivityContainer.attachApplication(wpc);
}
}
//RootActivityContainer.java:
boolean attachApplication(WindowProcessController app) throws RemoteException {
final String processName = app.mName;
boolean didSomething = false;
for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
final ActivityDisplay display = mActivityDisplays.get(displayNdx);
final ActivityStack stack = display.getFocusedStack();
if (stack != null) {
stack.getAllRunningVisibleActivitiesLocked(mTmpActivityList);
final ActivityRecord top = stack.topRunningActivityLocked();
final int size = mTmpActivityList.size();
for (int i = 0; i < size; i++) {
final ActivityRecord activity = mTmpActivityList.get(i);
if (activity.app == null && app.mUid == activity.info.applicationInfo.uid
&& processName.equals(activity.processName)) {
try {
if (mStackSupervisor.realStartActivityLocked(activity, app,
top == activity /* andResume */, true /* checkConfig */)) {
didSomething = true;
}
} catch (RemoteException e) {
......
}
}
}
}
}
......
return didSomething;
}
//ActivityStackSupervisor.java:
boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
boolean andResume, boolean checkConfig) throws RemoteException {
......
try {
r.startFreezingScreenLocked(proc, 0);
// schedule launch ticks to collect information about slow apps.
r.startLaunchTickingLocked();
r.setProcess(proc);
......
try {
// 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.icicle, r.persistentState, results, newIntents,
dc.isNextTransitionForward(), proc.createProfilerInfoIfNeeded(),
r.assistToken));
// Set desired final state.
final ActivityLifecycleItem lifecycleItem;
if (andResume) {
lifecycleItem = ResumeActivityItem.obtain(dc.isNextTransitionForward());
} else {
lifecycleItem = PauseActivityItem.obtain();
}
clientTransaction.setLifecycleStateRequest(lifecycleItem);
// Schedule transaction.
mService.getLifecycleManager().scheduleTransaction(clientTransaction);
......
} catch (RemoteException e) {
}
} finally {
}
......
return true;
}
attachApplication()关键代码 一直调用到realStartActivityLocked()。这里有几点注意。
这里完善了ActivityRecord,设置了进程等信息。总体上可以理解,应为ActivityRecord、ProcessRecord等由AMS/ATMS管理,这里将application绑定到了ATMS。
创建了ClientTransaction对象
设置了ClientTransaction的callback,为一个创建的LaunchActivityItem对象
设置生命周期,为创建的lifecycleItem对象
通过mService.getLifecycleManager().scheduleTransaction(clientTransaction)发送请求。这里的mService为ATMS,这里的mService.getLifecycleManager()即ClientLifecycleManager。
创建Application后,通过attachApplication()绑定到ATMS。当前还是在系统进程中。
创建了ClientTransaction对象和设置callback的相关代码,可以了解下。
//ClientTransaction.java
public void addCallback(ClientTransactionItem activityCallback) {
if (mActivityCallbacks == null) {
mActivityCallbacks = new ArrayList<>();
}
mActivityCallbacks.add(activityCallback);
}
public static ClientTransaction obtain(IApplicationThread client, IBinder activityToken) {
ClientTransaction instance = ObjectPool.obtain(ClientTransaction.class);
if (instance == null) {
instance = new ClientTransaction();
}
instance.mClient = client;
instance.mActivityToken = activityToken;
return instance;
}
//WindowProcessController.java:
IApplicationThread getThread() {
return mThread;
}
clientTransaction相关有大致了解后,直接看最后发送请求代码。
//ClientLifecycleManager.java:
void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
final IApplicationThread client = transaction.getClient();
transaction.schedule();
if (!(client instanceof Binder)) {
// If client is not an instance of Binder - it's a remote call and at this point it is
// safe to recycle the object. All objects used for local calls will be recycled after
// the transaction is executed on client in ActivityThread.
transaction.recycle();
}
}
//ClientTransaction.java
public void schedule() throws RemoteException {
mClient.scheduleTransaction(this);
}
mClient是啥呢?在创建ClientTransaction对象时赋值的。mClient在obtain()时传入的,即proc.getThread(),final ClientTransaction clientTransaction = ClientTransaction.obtain(proc.getThread(), r.appToken)。
ApplicationThread是ActivityThread的内部类,继承IApplicationThread.Stub,即是一个Binder。private class ApplicationThread extends IApplicationThread.Stub。
ApplicationThread是作为Activitythread和AMS/ATMS通信的桥梁。它与ActivityThread之间通过handler通信,AMS获取ApplicationThread的binder进行通信。
这里开始,实际就是从系统进程回到了应用进程。
这里的过程是应用进程通过binder(IPC)执行mgr.attachApplication()进入系统进程,ATMS通过回调ApplicationThread.scheduleTransaction(),然后通过handler回到应用进程的主线程。
ATMS回调ApplicationThread的方法,该方法在Binder线程池中的线程执行,所以需要使用Handler来切换线程到ActivityThread所在线程。
所以这里实际调用的就是ApplicationThread的 scheduleTransaction 方法。下面来看下。
//ActivityThread.java->ApplicationThread class:
@Override
public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
ActivityThread.this.scheduleTransaction(transaction);
}
//ClientTransactionHandler.java:
/** Prepare and schedule transaction for execution. */
void scheduleTransaction(ClientTransaction transaction) {
transaction.preExecute(this);
sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
}
//ActivityThread.java:
//public final class ActivityThread extends ClientTransactionHandler
private final TransactionExecutor mTransactionExecutor = new TransactionExecutor(this);
//TransactionExecutor.java:
/** Initialize an instance with transaction handler, that will execute all requested actions. */
public TransactionExecutor(ClientTransactionHandler clientTransactionHandler) {
mTransactionHandler = clientTransactionHandler;
}
//ActivityThread.java->H class:
class H extends Handler {
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;
}
}
}
可以看到scheduleTransaction() 最终通过hanlder进行处理的,执行到TransactionExecutor的execute()。
注意上面关于TransactionExecutor的创建,this是ActivityThread 作为参数闯入到构造函数中,ActivityThread是继承了ClientTransactionHandler的。mTransactionHandler即ActivityThread,这是应用进程的主线程,后面出现要知道。
//TransactionExecutor.java:
public void execute(ClientTransaction transaction) {
......
executeCallbacks(transaction);
executeLifecycleState(transaction);
mPendingActions.clear();
}
/** Cycle through all states requested by callbacks and execute them at proper times. */
@VisibleForTesting
public void executeCallbacks(ClientTransaction transaction) {
final List<ClientTransactionItem> callbacks = transaction.getCallbacks();
......
final int size = callbacks.size();
for (int i = 0; i < size; ++i) {
final ClientTransactionItem item = callbacks.get(i);
......
item.execute(mTransactionHandler, token, mPendingActions);
item.postExecute(mTransactionHandler, token, mPendingActions);
......
}
}
在上面realStartActivityLocked()中,设置的callback是LaunchActivityItem对象。这里execute()最终执行到LaunchActivityItem的execute()。 继续看
//LaunchActivityItem.java:
@Override
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);
client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
上面有说过的,这里的client就是ActivityThread。所以走到了ActivityThread的handleLaunchActivity()。
回到应用进程,创建activity并执行attach()和onCreate()
这里的client就是ActivityThread,上面也说过,其实是应用进程的主线程。
这里主要是创建出应用第一个Activity,并执行了attach()和onCreate()。
//ActivityThread.java:
public Activity handleLaunchActivity(ActivityClientRecord r,
PendingTransactionActions pendingActions, Intent customIntent) {
......
final Activity a = performLaunchActivity(r, customIntent);
......
return a;
}
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
ActivityInfo aInfo = r.activityInfo;
......
ComponentName component = r.intent.getComponent();
......
ContextImpl appContext = createBaseContextForActivity(r);
Activity activity = null;
try {
java.lang.ClassLoader cl = appContext.getClassLoader();
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
......
}
......
try {
Application app = r.packageInfo.makeApplication(false, mInstrumentation);
......
if (activity != null) {
......
appContext.setOuterContext(activity);
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()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
......
r.activity = activity;
}
r.setState(ON_CREATE);
}
.......
return activity;
}
这里是app启动中activity创建起来的最后一个阶段了。上面主要看3点
1.mInstrumentation.newActivity()创建了一个activity
2.activity.attach(),这个就是Activity中attach()的地方,将Context、ActivityThread、Instrumentation、Application、Window等等重要信息关联到了activity中。这里代码不列出了。
3.mInstrumentation.callActivityOnCreate()。执行了Activity的onCreate()方法。
下面来看下activity的创建和如何执行到onCreate()的。
创建activity
//Instrumentation.java:
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);
}
private AppComponentFactory getFactory(String pkg) {
......
}
//AppComponentFactory.java:
public @NonNull Activity instantiateActivity(@NonNull ClassLoader cl, @NonNull String className,
@Nullable Intent intent)
throws InstantiationException, IllegalAccessException, ClassNotFoundException {
return (Activity) cl.loadClass(className).newInstance();
}
getFactory()获取的是AppComponentFactory对象。通过反射生成了Activity。
执行Activity.onCreate()
// Instrumentation.java
public void callActivityOnCreate(Activity activity, Bundle icicle) {
prePerformCreate(activity);
activity.performCreate(icicle);
postPerformCreate(activity);
}
// Activity.java
final void performCreate(Bundle icicle) {
performCreate(icicle, null);
}
@UnsupportedAppUsage
final void performCreate(Bundle icicle, PersistableBundle persistentState) {
......
if (persistentState != null) {
onCreate(icicle, persistentState);
} else {
onCreate(icicle);
}
......
}
到此,一个应用的启动过程算是完成了。
网友评论