美文网首页
Android AMS启动Activity(2)

Android AMS启动Activity(2)

作者: Bfmall | 来源:发表于2023-03-07 15:00 被阅读0次

接着上篇: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);
    }
    ......
}

到此,一个应用的启动过程算是完成了。

参考:https://www.cnblogs.com/fanglongxiang/p/13670328.html

相关文章

网友评论

      本文标题:Android AMS启动Activity(2)

      本文链接:https://www.haomeiwen.com/subject/lpqbldtx.html