❤️ Android startActivity源码分析(含启动新应用) ❤️(下)

简介: 9、ActivityTaskSupervisor.class9.1 startSpecificActivity()9.2 进程已启动9.2.1 realStartActivityLocked()9.2.2 ClientLifecycleManager.scheduleTransaction()9.2.3 ClientTransaction.schedule()9.2.4 ApplicationThread.scheduleTransaction()9.2.5 ClientTransactionHandler.scheduleTransaction()

9、ActivityTaskSupervisor.class


       frameworks/base/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java


public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
      ...
}


9.1 startSpecificActivity()


    void startSpecificActivity(ActivityRecord r, boolean andResume, boolean checkConfig) {
        // 此 Activity 的 应用程序(进程) 是否已在运行?
        final WindowProcessController wpc =
                mService.getProcessController(r.processName, r.info.applicationInfo.uid);
        boolean knownToBeDead = false;
        if (wpc != null && wpc.hasThread()) {
            try {
                //进程已启动
                //注释1:开始启动activity
                realStartActivityLocked(r, wpc, andResume, checkConfig);
                return;
            } catch (RemoteException e) {
            }
        }
        r.notifyUnknownVisibilityLaunchedForKeyguardTransition();
        final boolean isTop = andResume && r.isTopRunningActivity();
        //注释2:进程未启动
        mService.startProcessAsync(r, knownToBeDead, isTop, isTop ? "top-activity" : "activity");
    }


注释1:进程已启动。

注释2:进程未启动。


9.2 进程已启动


9.2.1 realStartActivityLocked()


    boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
            boolean andResume, boolean checkConfig) throws RemoteException {
        ...
                //创建 Activity 启动的 transaction
                final ClientTransaction clientTransaction = ClientTransaction.obtain(
                        proc.getThread(), r.appToken);
                final boolean isTransitionForward = r.isTransitionForward();
                clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
                        System.identityHashCode(r), r.info,
                        mergedConfiguration.getGlobalConfiguration(),
                        mergedConfiguration.getOverrideConfiguration(), r.compat,
                        r.launchedFromPackage, task.voiceInteractor, proc.getReportedProcState(),
                        r.getSavedState(), r.getPersistentSavedState(), results, newIntents,
                        r.takeOptions(), isTransitionForward,
                        proc.createProfilerInfoIfNeeded(), r.assistToken, activityClientController,
                        r.createFixedRotationAdjustmentsIfNeeded(), r.shareableActivityToken,
                        r.getLaunchedFromBubble()));
                // Set desired final state.
                final ActivityLifecycleItem lifecycleItem;
                if (andResume) {
                    lifecycleItem = ResumeActivityItem.obtain(isTransitionForward);
                } else {
                    lifecycleItem = PauseActivityItem.obtain();
                }
                clientTransaction.setLifecycleStateRequest(lifecycleItem);
                // Schedule transaction.
                mService.getLifecycleManager().scheduleTransaction(clientTransaction);
        ...
        return true;
    }


这的 mService 就是 ActivityTaskManagerService(ATMS) 的实例。mService.getLifecycleManager() 返回的是一个 ClientLifecycleManager 对象。想看 scheduleTransaction() 是干嘛的 只能找它了。


9.2.2 ClientLifecycleManager.scheduleTransaction()

       frameworks/base/services/core/java/com/android/server/wm/ClientLifecycleManager.java


    //这里咱们传入的是一个启动 Activity 的 transaction
    void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
        final IApplicationThread client = transaction.getClient();
        //注释1
        transaction.schedule();
        if (!(client instanceof Binder)) {
            // 如果 client 不是Binder的实例,则它是一个远程调用,此时可以安全地回收该对象。
            // 在ActivityThread中的客户端上执行transaction后,将回收用于本地调用的所有对象。
            transaction.recycle();
        }
    }


从方法中看出 transaction 是个 ClientTransaction 。那咱直接去找他。


9.2.3 ClientTransaction.schedule()


    /** Target client. */
    private IApplicationThread mClient;
    public void schedule() throws RemoteException {
        mClient.scheduleTransaction(this);
    }


看到 IApplicationThread ,咱们直接去找 ApplicationThread


9.2.4 ApplicationThread.scheduleTransaction()


       frameworks/base/core/java/android/app/ActivityThread.java


     ApplicationThread 属于 ActivityThread 的内部类。


public final class ActivityThread extends ClientTransactionHandler
        implements ActivityThreadInternal {
    ...
    private class ApplicationThread extends IApplicationThread.Stub {
        ...
        @Override
        public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
            ActivityThread.this.scheduleTransaction(transaction);
        }
        ...
    }
    ...
}


ActivityThread 类中是没有 scheduleTransaction 方法的,通常遇到这种状况,直接找其父类 ClientTransactionHandler。


9.2.5 ClientTransactionHandler.scheduleTransaction()


       frameworks/base/core/java/android/app/ClientTransactionHandler.java


public abstract class ClientTransactionHandler {
    /** Prepare and schedule transaction for execution. */
    void scheduleTransaction(ClientTransaction transaction) {
        transaction.preExecute(this);
        sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
    }
}


从这里看到 他调用 sendMessage() 方法发送了个 ActivityThread.H.EXECUTE_TRANSACTION 消息,咱们回到其子类 ActivityThread 中查看。


9.2.6 ActivityThread.H.handleMessage()


       这里的 HActivityThread 的 内部类。


1.    // An executor that performs multi-step transactions.
    private final TransactionExecutor mTransactionExecutor = new TransactionExecutor(this);
    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()) {
                        transaction.recycle();
                    }
                    break;
                    ...
            }
        }
    }


这里的 mTransactionExecutortransactions 的执行者。


9.2.7 TransactionExecutor.execute()


       frameworks/base/core/java/android/app/servertransaction/TransactionExecutor.java


    public void execute(ClientTransaction transaction) {
        ...
        executeCallbacks(transaction);
        ...
    }


9.2.8 TransactionExecutor.executeCallbacks()


    /** 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 IBinder token = transaction.getActivityToken();
        ActivityClientRecord r = mTransactionHandler.getActivityClient(token);
        ...
        final int size = callbacks.size();
        for (int i = 0; i < size; ++i) {
            ...
            if (postExecutionState != UNDEFINED && r != null) {
                // 重点
                final boolean shouldExcludeLastTransition =
                        i == lastCallbackRequestingState && finalState == postExecutionState;
                cycleToPath(r, postExecutionState, shouldExcludeLastTransition, transaction);
            }
        }
    }


      这个方法的重点是 cycleToPath() ,咱们继续。


9.2.9 TransactionExecutor.cycleToPath()


    private void cycleToPath(ActivityClientRecord r, int finish, boolean excludeLastState,
            ClientTransaction transaction) {
        final int start = r.getLifecycleState();
        //IntArray:实现不断增长的int基元数组。
        //获取此次要执行生命周期的路径path
        final IntArray path = mHelper.getLifecyclePath(start, finish, excludeLastState);
        performLifecycleSequence(r, path, transaction);
    }1.


9.2.10 TransactionExecutor.performLifecycleSequence()


    /** Transition the client through previously initialized state sequence. */
    private void performLifecycleSequence(ActivityClientRecord r, IntArray path,
            ClientTransaction transaction) {
        final int size = path.size();
        for (int i = 0, state; i < size; i++) {
            state = path.get(i);
            switch (state) {
                case ON_CREATE:
                    mTransactionHandler.handleLaunchActivity(r, mPendingActions,
                            null /* customIntent */);
                    break;
                case ON_START:
                    mTransactionHandler.handleStartActivity(r, mPendingActions,
                            null /* activityOptions */);
                    break;
                case ON_RESUME:
                    mTransactionHandler.handleResumeActivity(r, false /* finalStateRequest */,
                            r.isForward, "LIFECYCLER_RESUME_ACTIVITY");
                    break;
                case ON_PAUSE:
                    mTransactionHandler.handlePauseActivity(r, false /* finished */,
                            false /* userLeaving */, 0 /* configChanges */, mPendingActions,
                            "LIFECYCLER_PAUSE_ACTIVITY");
                    break;
                case ON_STOP:
                    mTransactionHandler.handleStopActivity(r, 0 /* configChanges */,
                            mPendingActions, false /* finalStateRequest */,
                            "LIFECYCLER_STOP_ACTIVITY");
                    break;
                case ON_DESTROY:
                    mTransactionHandler.handleDestroyActivity(r, false /* finishing */,
                            0 /* configChanges */, false /* getNonConfigInstance */,
                            "performLifecycleSequence. cycling to:" + path.get(size - 1));
                    break;
                case ON_RESTART:
                    mTransactionHandler.performRestartActivity(r, false /* start */);
                    break;
                default:
                    throw new IllegalArgumentException("Unexpected lifecycle state: " + state);
            }
        }
    }


到这里咱们终于看到了熟悉的内容,Activity的生命周期,好激动哈哈。


这里咱们以 ON_CREATE 为例。从上面代码看出 ON_CREATE 等其实就是个int值(常量),这里咱就不多描述了。mTransactionHandler ClientTransactionHandler 的实例,直接看handleLaunchActivity() 方法。


9.2.11 ClientTransactionHandler.handleLaunchActivity()


       frameworks/base/core/java/android/app/ClientTransactionHandler.java


public abstract class ClientTransactionHandler {
    ...
    /** Perform activity launch. */
    public abstract Activity handleLaunchActivity(@NonNull ActivityClientRecord r,
            PendingTransactionActions pendingActions, Intent customIntent);
    ...    
}


从上面看出 handleLaunchActivity() 是抽象方法,ActivityThread 做为其子类,只能找其子类 ActivityThread 看看具体实现。


9.2.12 ActivityThread.handleLaunchActivity()


    /**
     * Extended implementation of activity launch. Used when server requests a launch or relaunch.
     */
    @Override
    public Activity handleLaunchActivity(ActivityClientRecord r,
            PendingTransactionActions pendingActions, Intent customIntent) {
        // 在创建 activity 之前初始化
        if (ThreadedRenderer.sRendererEnabled
                && (r.activityInfo.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0) {
            HardwareRenderer.preload();
        }
        //初始化 Activity 的 WindowManager,每一个 Activity 都会对应一个"窗口"。
        WindowManagerGlobal.initialize();
        // 提示 GraphicsEnvironment Activity 正在进程中启动。
        GraphicsEnvironment.hintActivityLaunch();
        //这里重点:Activity 启动的核心实现。
        final Activity a = performLaunchActivity(r, customIntent);
        ...
        return a;
    }1.



  performLaunchActivity()Activity 启动的核心实现。具体咱们往下看


9.2.13 ActivityThread.performLaunchActivity()


    /**  Core implementation of activity launch. */
    private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
        ...
        ContextImpl appContext = createBaseContextForActivity(r);
        Activity activity = null;
        try {
            java.lang.ClassLoader cl = appContext.getClassLoader();
            //注释1: 新实例化的 Activity 对象。
            activity = mInstrumentation.newActivity(
                    cl, component.getClassName(), r.intent);
            ...
        } catch (Exception e) {
            ...
        }
                //重点:调用activity.attach()。
                //建立 Activity 与 Context 之间的联系。
                //创建 PhoneWindow 对象,并与 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, r.shareableActivityToken);
                //persistableMode属性设置为: ActivityInfo.PERSIST_ACROSS_REBOOTS(persistAcrossReboots);
                //注释2:执行 Activity 的 onCreate() 方法。
                if (r.isPersistable()) {
                    mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
                } else {
                    mInstrumentation.callActivityOnCreate(activity, r.state);
                }
        return activity;
    }


这里首先看看 mInstrumentation 其实就是 Instrumentation 。 在本文 startActivityForResult 部分也有用到。Instrumentation 负责 ApplicationActivity 的建立和生命周期控制。


这里用到了他的两个方法咱们一起看看。


9.2.14 Instrumentation.newActivity()


    /**
     * @param cl 用于实例化对象的类加载器(ClassLoader)。
     * @param className 实现 Activity 对象的类的名称。
     * @param intent 指定要实例化的活动类的 Intent 对象。
     * 
     * @return 新实例化的 Activity 对象。
     */
    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);
    }


   pkg 就是 intent 所在的包名。


       getFactory(pkg) 通过获取到的包名 得到 AppComponentFactory 。然后调用其 instantiateActivity() 方法获取 Activity


9.2.14.1 Instrumentation.getFactory()


    private AppComponentFactory getFactory(String pkg) {
        if (pkg == null) {
            ...
            return AppComponentFactory.DEFAULT;
        }
        if (mThread == null) {
            ....
            return AppComponentFactory.DEFAULT;
        }
        LoadedApk apk = mThread.peekPackageInfo(pkg, true);
        // This is in the case of starting up "android".
        if (apk == null) apk = mThread.getSystemContext().mPackageInfo;
        return apk.getAppFactory();
    }


9.2.14.2 AppComponentFactory.instantiateActivity()


       frameworks/base/core/java/android/app/AppComponentFactory.java


/**
  * 用于控制 manifest 元素实例化的接口。
  *
  * @see #instantiateApplication
  * @see #instantiateActivity
  * @see #instantiateClassLoader
  * @see #instantiateService
  * @see #instantiateReceiver
  * @see #instantiateProvider
  */
public class AppComponentFactory {
      ...
}


instantiateActivity()


    /**
     * 此方法仅用于提供用于实例化的钩子。
     * 它不提供对 Activity 对象的早期访问。
     * 返回的对象还不会被初始化为 Context 并且不应该用于与其他 android API 交互。
     */
    public @NonNull Activity instantiateActivity(@NonNull ClassLoader cl, @NonNull String className,
            @Nullable Intent intent)
            throws InstantiationException, IllegalAccessException, ClassNotFoundException {
        return (Activity) cl.loadClass(className).newInstance();
    }


这里通过反射拿到 Activity 的实例。


9.2.15 Instrumentation.callActivityOnCreate()


1.    /**
     * 执行 Activity#onCreate方法的调用。
     *
     * @param activity 正在创建的 activity 。
     * @param icicle 将以前冻结的状态(或null)传递给 onCreate() 。
     */
    public void callActivityOnCreate(Activity activity, Bundle icicle) {
        prePerformCreate(activity);
        //重点
        activity.performCreate(icicle);
        postPerformCreate(activity);
    }


     从这里可以看到即将进入 Activity 的内部


9.2.15.1 Activity.performCreate()


    final void performCreate(Bundle icicle) {
        performCreate(icicle, null);
    }
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
    final void performCreate(Bundle icicle, PersistableBundle persistentState) {
        ...
        //重点
        if (persistentState != null) {
            onCreate(icicle, persistentState);
        } else {
            onCreate(icicle);
        }
        ...
    }


 看到这里,startSpecificActivity() 方法中的 进程已启动的状态算是完结。startActivity 启动成功。结合 9.2.13 ActivityThread.performLaunchActivity() 查看 Activity 中的 attach() 方法调用早于 onCreate() 方法。


       下面让我们回到 9.1 startSpecificActivity() 中查看进程未启动的流程情况。


9.3 进程未启动


       既然进程未启动那肯定先启动进程了。咱们接着看。


    final ActivityTaskManagerService mService;
    void startSpecificActivity(ActivityRecord r, boolean andResume, boolean checkConfig) {
        ....
        mService.startProcessAsync(r, knownToBeDead, isTop, isTop ? "top-activity" : "activity");
    }


从这里看到 mService 其实就是 ATMS ,走着。


9.3.1 ATMS.startProcessAsync()


    void startProcessAsync(ActivityRecord activity, boolean knownToBeDead, boolean isTop,
            String hostingType) {
        try {
            ...
            // 发布消息以启动进程,以避免在持有 ATMS 锁的情况下调用 AMS 可能出现死锁。
            final Message m = PooledLambda.obtainMessage(ActivityManagerInternal::startProcess,
                    mAmInternal, activity.processName, activity.info.applicationInfo, knownToBeDead,
                    isTop, hostingType, activity.intent.getComponent());
            mH.sendMessage(m);
        } finally {
            Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
        }
    }


9.3.2 ActivityManagerInternal.startProcess()


       frameworks/base/core/java/android/app/ActivityManagerInternal.java


/**
 * Activity manager local system service interface.
 */
public abstract class ActivityManagerInternal {
    /** Starts a given process. */
    public abstract void startProcess(String processName, ApplicationInfo info,
            boolean knownToBeDead, boolean isTop, String hostingType, ComponentName hostingName);
}


   这里是个抽象类,咱们去找其实现类 ActivityManagerService.LocalService


9.3.3 ActivityManagerService.LocalService.startProcess()

       frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java


public class ActivityManagerService extends IActivityManager.Stub
        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback, ActivityManagerGlobalLock {   
    ...
    @VisibleForTesting
    public final class LocalService extends ActivityManagerInternal
            implements ActivityManagerLocal {
        ...
        @Override
        public void startProcess(String processName, ApplicationInfo info, boolean knownToBeDead,
                boolean isTop, String hostingType, ComponentName hostingName) {
            try {
                synchronized (ActivityManagerService.this) {
                    // 如果该进程称为top app,请设置一个提示,以便在启动该进程时,可以立即应用最高优先级,以避免在附加top app进程之前cpu被其他进程抢占。
                    startProcessLocked(processName, info, knownToBeDead, 0 /* intentFlags */,
                            new HostingRecord(hostingType, hostingName, isTop),
                            ZYGOTE_POLICY_FLAG_LATENCY_SENSITIVE, false /* allowWhileBooting */,
                            false /* isolated */);
                }
            } finally {
            }
        }
    }
}    


9.3.4 ActivityManagerService.startProcessLocked()


    /**
     * Process management.
     */
    final ProcessList mProcessList;
    @GuardedBy("this")
    final ProcessRecord startProcessLocked(String processName,
            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
            HostingRecord hostingRecord, int zygotePolicyFlags, boolean allowWhileBooting,
            boolean isolated, boolean keepIfLarge) {
        return mProcessList.startProcessLocked(processName, info, knownToBeDead, intentFlags,
                hostingRecord, zygotePolicyFlags, allowWhileBooting, isolated, 0 /* isolatedUid */,
                keepIfLarge, null /* ABI override */, null /* entryPoint */,
                null /* entryPointArgs */, null /* crashHandler */);
    }


可以看出,这里的 mProcessList 就是 ProcessList。


9.3.5 ProcessList.startProcessLocked()


       frameworks/base/services/core/java/com/android/server/am/ProcessList.java


    @GuardedBy("mService")
    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
            boolean knownToBeDead, int intentFlags, HostingRecord hostingRecord,
            int zygotePolicyFlags, boolean allowWhileBooting, boolean isolated, int isolatedUid,
            boolean keepIfLarge, String abiOverride, String entryPoint, String[] entryPointArgs,
            Runnable crashHandler) {
        ...
        final boolean success =
                startProcessLocked(app, hostingRecord, zygotePolicyFlags, abiOverride);
        checkSlow(startTime, "startProcess: done starting proc!");
        return success ? app : null;
    }
    ------------分割线-------------
    @GuardedBy("mService")
    final boolean startProcessLocked(ProcessRecord app, HostingRecord hostingRecord,
            int zygotePolicyFlags, String abiOverride) {
        return startProcessLocked(app, hostingRecord, zygotePolicyFlags,
                false /* disableHiddenApiChecks */, false /* disableTestApiChecks */,
                false /* mountExtStorageFull */, abiOverride);
    }
    ------------分割线-------------
    /**
     * @return {@code true} if process start is successful, false otherwise.
     */
    @GuardedBy("mService")
    boolean startProcessLocked(ProcessRecord app, HostingRecord hostingRecord,
            int zygotePolicyFlags, boolean disableHiddenApiChecks, boolean disableTestApiChecks,
            boolean mountExtStorageFull, String abiOverride) {
            ...
            return startProcessLocked(hostingRecord, entryPoint, app, uid, gids,
                    runtimeFlags, zygotePolicyFlags, mountExternal, seInfo, requiredAbi,
                    instructionSet, invokeWith, startTime);
    }
    ------------分割线-------------
    @GuardedBy("mService")
    boolean startProcessLocked(HostingRecord hostingRecord, String entryPoint, ProcessRecord app,
            int uid, int[] gids, int runtimeFlags, int zygotePolicyFlags, int mountExternal,
            String seInfo, String requiredAbi, String instructionSet, String invokeWith,
            long startTime) {
                ...
                //终于到重点了。
                final Process.ProcessStartResult startResult = startProcess(hostingRecord,
                        entryPoint, app,
                        uid, gids, runtimeFlags, zygotePolicyFlags, mountExternal, seInfo,
                        requiredAbi, instructionSet, invokeWith, startTime);
                handleProcessStartedLocked(app, startResult.pid, startResult.usingWrapper,
                        startSeq, false);
                ...
    }


 反复调用,终于看到了关键代码 startProcess()


9.3.6 ProcessList.startProcess()


    private Process.ProcessStartResult startProcess(HostingRecord hostingRecord, String entryPoint,
            ProcessRecord app, int uid, int[] gids, int runtimeFlags, int zygotePolicyFlags,
            int mountExternal, String seInfo, String requiredAbi, String instructionSet,
            String invokeWith, long startTime) {
            ...
            final Process.ProcessStartResult startResult;
            if (hostingRecord.usesWebviewZygote()) {
                //进程是否应该从 webview zygote 产生
                startResult = startWebView(entryPoint,
                        app.processName, uid, uid, gids, runtimeFlags, mountExternal,
                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
                        app.info.dataDir, null, app.info.packageName, app.mDisabledCompatChanges,
                        new String[]{PROC_START_SEQ_IDENT + app.startSeq});
            } else if (hostingRecord.usesAppZygote()) {
                //进程是否应该从应用程序 zygote 中产生
                final AppZygote appZygote = createAppZygoteForProcessIfNeeded(app);
                // 我们无法隔离应用程序数据和存储数据,因为父 zygote 已经这样做了。
                startResult = appZygote.getProcess().start(entryPoint,
                        app.processName, uid, uid, gids, runtimeFlags, mountExternal,
                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
                        app.info.dataDir, null, app.info.packageName,
                        /*zygotePolicyFlags=*/ ZYGOTE_POLICY_FLAG_EMPTY, isTopApp,
                        app.mDisabledCompatChanges, pkgDataInfoMap, whitelistedAppDataInfoMap,
                        false, false,
                        new String[]{PROC_START_SEQ_IDENT + app.startSeq});
            } 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, zygotePolicyFlags,
                        isTopApp, app.mDisabledCompatChanges, pkgDataInfoMap,
                        whitelistedAppDataInfoMap, bindMountAppsData, bindMountAppStorageDirs,
                        new String[]{PROC_START_SEQ_IDENT + app.startSeq});
            }
            ...
   }


无论那种情况都会调用 Process.start() ;


9.3.7 Process.start()


       frameworks/base/core/java/android/os/Process.java


    /**
     * State associated with the zygote process.
     */
    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,
                                           int zygotePolicyFlags,
                                           boolean isTopApp,
                                           @Nullable long[] disabledCompatChanges,
                                           @Nullable Map<String, Pair<String, Long>>
                                                   pkgDataInfoMap,
                                           @Nullable Map<String, Pair<String, Long>>
                                                   whitelistedDataInfoMap,
                                           boolean bindMountAppsData,
                                           boolean bindMountAppStorageDirs,
                                           @Nullable String[] zygoteArgs) {
        return ZYGOTE_PROCESS.start(processClass, niceName, uid, gid, gids,
                    runtimeFlags, mountExternal, targetSdkVersion, seInfo,
                    abi, instructionSet, appDataDir, invokeWith, packageName,
                    zygotePolicyFlags, isTopApp, disabledCompatChanges,
                    pkgDataInfoMap, whitelistedDataInfoMap, bindMountAppsData,
                    bindMountAppStorageDirs, zygoteArgs);
    }


这里的 ZYGOTE_PROCESS 就是 ZygoteProcess 。调用其 start() 方法。


9.3.8 ZygoteProcess.start()


       frameworks/base/core/java/android/os/ZygoteProcess.java


    /**
     * 开始一个新的进程。
     * 如果启用了进程,则会创建一个新进程并在那里执行processClass 的静态main() 函数。
     * 该函数返回后进程将继续运行。
     * 
     * 如果未启用进程,则会在调用者进程中创建一个新线程并在那里调用 processclass 的 main()。
     * 
     * niceName 参数,如果不是空字符串,则是一个自定义名称,用于提供给进程而不是使用 processClass。
     * 这允许您创建易于识别的进程,即使您使用相同的基本 processClass 来启动它们。
     *
     * 当 invokeWith 不为 null 时,进程将作为一个新的 app 而不是 zygote fork 启动。
     * 请注意,这仅适用于 uid 0 或当runtimeFlags 包含 DEBUG_ENABLE_DEBUGGER 时。
     *
     * @param processClass 用作进程主入口点的类。
     * @param niceName 用于进程的更易读的名称。
     * @param uid 进程将在其下运行的用户 ID。
     * @param gid 进程将在其下运行的组 ID。
     * @param gids 与进程关联的附加组 ID。
     * @param runtimeFlags 附加标志。
     * @param targetSdkVersion 应用的目标 SDK 版本。
     * @param seInfo null-ok 新进程的 SELinux 信息。
     * @param abi 非空此应用程序应使用的 ABI。
     * @param instructionsSet null-确定要使用的指令集。
     * @param appDataDir null-ok 应用程序的数据目录。
     * @param invokeWith null-ok 要调用的命令。
     * @param packageName null-ok 这个进程所属的包名。
     * @param zygotePolicyFlags 用于确定如何启动应用程序的标志。
     * @param isTopApp 进程是否为高优先级应用程序启动。
     * @param disabledCompatChanges 正在启动的进程的禁用兼容更改的 null-ok 列表。
     * @param pkgDataInfoMap 从相关包名称映射到私有数据目录卷 UUID 和 inode 编号。
     * @param allowlistedDataInfoList 从允许的包名称映射到私有数据目录卷 UUID 和 inode 编号。
     * @param bindMountAppsData zygote 是否需要挂载 CE 和 DE 数据。
     * @param bindMountAppStorageDirs zygote 是否需要挂载Android/obb 和Android/data。
     *
     * @param zygoteArgs 提供给 Zygote 进程的附加参数。
     * @return 一个对象,描述尝试启动进程的结果。
     * @throws RuntimeException 出现致命启动失败
     */
    //这里从上一个方法传来一大堆参数就不多描述了
    public final Process.ProcessStartResult start(...) {
        ...
            return startViaZygote(processClass, niceName, uid, gid, gids,
                    runtimeFlags, mountExternal, targetSdkVersion, seInfo,
                    abi, instructionSet, appDataDir, invokeWith, /*startChildZygote=*/ false,
                    packageName, zygotePolicyFlags, isTopApp, disabledCompatChanges,
                    pkgDataInfoMap, allowlistedDataInfoList, bindMountAppsData,
                    bindMountAppStorageDirs, zygoteArgs);
        ...
    }


9.3.9 ZygoteProcess.startViaZygote()


    //这里从上一个方法传来一大堆参数就不多描述了
    private Process.ProcessStartResult startViaZygote(...)
                                                      throws ZygoteStartFailedEx {
        ...
        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),
                                              zygotePolicyFlags,
                                              argsForZygote);
        }
    }


在看 zygoteSendArgsAndGetResult() 之前咱们看看 openZygoteSocketIfNeeded(abi)


9.3.10 ZygoteProcess.openZygoteSocketIfNeeded()


1.    /**
     * 尝试打开一个 session socket到具有兼容 ABI 的 Zygote 进程(如果尚未打开)。 如果兼容的 session socket已经打开,则返回该 session socket。
     *
     * 此功能可能会阻塞,并且可能必须尝试连接到多个 Zygotes 才能找到合适的 Zygotes。 需要保持 mLock。
     */
    @GuardedBy("mLock")
    private ZygoteState openZygoteSocketIfNeeded(String abi) throws ZygoteStartFailedEx {
        try {
            attemptConnectionToPrimaryZygote();
            ...
    }
    ------------分割线-------------
    /**
     * 如果Primary Zygote不存在或已断开连接,则为它创建一个 ZygoteState。
     */
    @GuardedBy("mLock")
    private void attemptConnectionToPrimaryZygote() throws IOException {
        if (primaryZygoteState == null || primaryZygoteState.isClosed()) {
            primaryZygoteState =
                    ZygoteState.connect(mZygoteSocketAddress, mUsapPoolSocketAddress);
            ...
        }
    }
    ------------分割线-------------
    static ZygoteState connect(@NonNull LocalSocketAddress zygoteSocketAddress,
            @Nullable LocalSocketAddress usapSocketAddress)
            throws IOException {
        ...
        //创建LocalSocket
        final LocalSocket zygoteSessionSocket = new LocalSocket();
            //将zygoteSessionSocket连接到端点。
            //只能在尚未连接的实例上调用。
            zygoteSessionSocket.connect(zygoteSocketAddress);
        ...
    }


  打开了 ZygoteSocket 之后咱们看看 zygoteSendArgsAndGetResult();


9.4.11 ZygoteProcess.zygoteSendArgsAndGetResult()


    @GuardedBy("mLock")
    private Process.ProcessStartResult zygoteSendArgsAndGetResult(
            ZygoteState zygoteState, int zygotePolicyFlags, @NonNull ArrayList<String> args)
            throws ZygoteStartFailedEx {
        ...
        String msgStr = args.size() + "\n" + String.join("\n", args) + "\n";        
        return attemptZygoteSendArgsAndGetResult(zygoteState, msgStr);
    }


9.4.12 ZygoteProcess.attemptZygoteSendArgsAndGetResult()


    private Process.ProcessStartResult attemptZygoteSendArgsAndGetResult(
            ZygoteState zygoteState, String msgStr) throws ZygoteStartFailedEx {
        try {
            final BufferedWriter zygoteWriter = zygoteState.mZygoteOutputWriter;
            final DataInputStream zygoteInputStream = zygoteState.mZygoteInputStream;
            //写,调用zygote(ZygoteInit)。
            zygoteWriter.write(msgStr);
            zygoteWriter.flush();
            // Always read the entire result from the input stream to avoid leaving
            // bytes in the stream for future process starts to accidentally stumble
            // upon.
            Process.ProcessStartResult result = new Process.ProcessStartResult();
            //读,造成阻塞
            result.pid = zygoteInputStream.readInt();
            result.usingWrapper = zygoteInputStream.readBoolean();
            if (result.pid < 0) {
                throw new ZygoteStartFailedEx("fork() failed");
            }
            return result;
        } catch (IOException ex) {
            zygoteState.close();
            Log.e(LOG_TAG, "IO Exception while communicating with Zygote - "
                    + ex.toString());
            throw new ZygoteStartFailedEx(ex);
        }
    }


9.4.13 ZygoteInit.main()


    @UnsupportedAppUsage
    public static void main(String[] argv) {
            ...
            // zygote 永久循环。
            caller = zygoteServer.runSelectLoop(abiList);
    }


9.4.14 ZygoteService.runSelectLoop()


    /**
     * 运行 zygote 进程的选择循环。 在新连接发生时接受新连接,并从连接中读取一次一个 spawn-request 值的命令。
     * @param abiList 此 zygote 支持的 ABI 列表。
     */
    Runnable runSelectLoop(String abiList) {
        ...
                            //Session socket accepted from the Zygote server socket
                            ZygoteConnection connection = peers.get(pollIndex);
                            //通过 fork 启动 子进程(应用程序)
                            final Runnable command = connection.processOneCommand(this);
        ...                                   
    }


9.4.15 ZygoteConnection.processOneCommand()


       frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java


    Runnable processOneCommand(ZygoteServer zygoteServer) {
        ...
        pid = Zygote.forkAndSpecialize(parsedArgs.mUid, parsedArgs.mGid, parsedArgs.mGids,
                parsedArgs.mRuntimeFlags, rlimits, parsedArgs.mMountExternal, parsedArgs.mSeInfo,
                parsedArgs.mNiceName, fdsToClose, fdsToIgnore, parsedArgs.mStartChildZygote,
                parsedArgs.mInstructionSet, parsedArgs.mAppDataDir, parsedArgs.mIsTopApp,
                parsedArgs.mPkgDataInfoList, parsedArgs.mWhitelistedDataInfoList,
                parsedArgs.mBindMountAppDataDirs, parsedArgs.mBindMountAppStorageDirs);
        ...
    }


 fork 出一个新的进程(APP),一个APP的程序入口就是ActivityThread.main()


9.4.15 ActivityThread.main()


       frameworks/base/core/java/android/app/ActivityThread.java


       在 ActivityThread 初始化的时候,就已经创建消息循环了,所以在主线程里面创建 Handler 不需要指定 Looper,而如果在其他线程使用Handler,则需要 单独使用Looper.prepare()和Looper.loop() 创建消息循环。


    public static void main(String[] args) {
        ...
        //初始化当前进程的 Looper 对象
        Looper.prepareMainLooper();
        ...
        ActivityThread thread = new ActivityThread();
        //此处创建Application
        thread.attach(false, startSeq);
        if (sMainThreadHandler == null) {
            sMainThreadHandler = thread.getHandler();
        }
        if (false) {
            Looper.myLooper().setMessageLogging(new
                    LogPrinter(Log.DEBUG, "ActivityThread"));
        }
        // 调用 Looper 的 loop 方法开启无限循环。
        Looper.loop();
        throw new RuntimeException("Main thread loop unexpectedly exited");
    }


 Looper :从 MessageQueue 中取出 Message,然后处理 Message 中指定的任务(startActivity)。


       至此,不管是调用 startActivity() 启动页面,还是调用 startActivity() 开启其他进程的界面都算完成了。


       如有问题麻烦指正。


相关推荐


❤️ Android 应用是如何启动的?❤️


❤️Android Runtime (ART) 和 Dalvik❤️


❤️Android Apk 的打包过程 ❤️ 只需两幅图


❤️Android 从源码解读 Apk 的安装过程 ❤️

相关文章
|
24天前
|
JSON Java Android开发
探索安卓开发之旅:打造你的第一个天气应用
【10月更文挑战第30天】在这个数字时代,掌握移动应用开发技能无疑是进入IT行业的敲门砖。本文将引导你开启安卓开发的奇妙之旅,通过构建一个简易的天气应用来实践你的编程技能。无论你是初学者还是有一定经验的开发者,这篇文章都将成为你宝贵的学习资源。我们将一步步地深入到安卓开发的世界中,从搭建开发环境到实现核心功能,每个环节都充满了发现和创造的乐趣。让我们开始吧,一起在代码的海洋中航行!
|
24天前
|
存储 搜索推荐 Java
打造个性化安卓应用:从设计到实现
【10月更文挑战第30天】在数字化时代,拥有一个个性化的安卓应用不仅能够提升用户体验,还能加强品牌识别度。本文将引导您了解如何从零开始设计和实现一个安卓应用,涵盖用户界面设计、功能开发和性能优化等关键环节。我们将以一个简单的记事本应用为例,展示如何通过Android Studio工具和Java语言实现基本功能,同时确保应用流畅运行。无论您是初学者还是希望提升现有技能的开发者,这篇文章都将为您提供宝贵的见解和实用的技巧。
|
28天前
|
搜索推荐 开发工具 Android开发
打造个性化Android应用:从设计到实现的旅程
【10月更文挑战第26天】在这个数字时代,拥有一个能够脱颖而出的移动应用是成功的关键。本文将引导您了解如何从概念化阶段出发,通过设计、开发直至发布,一步步构建一个既美观又实用的Android应用。我们将探讨用户体验(UX)设计的重要性,介绍Android开发的核心组件,并通过实际案例展示如何克服开发中的挑战。无论您是初学者还是有经验的开发者,这篇文章都将为您提供宝贵的见解和实用的技巧,帮助您在竞争激烈的应用市场中脱颖而出。
|
1月前
|
算法 Java 数据库
Android 应用的主线程在什么情况下会被阻塞?
【10月更文挑战第20天】为了避免主线程阻塞,我们需要合理地设计和优化应用的代码。将耗时操作移到后台线程执行,使用异步任务、线程池等技术来提高应用的并发处理能力。同时,要注意避免出现死循环、不合理的锁使用等问题。通过这些措施,可以确保主线程能够高效地运行,提供流畅的用户体验。
39 2
|
2月前
|
Java API Android开发
安卓应用程序开发的新手指南:从零开始构建你的第一个应用
【10月更文挑战第20天】在这个数字技术不断进步的时代,掌握移动应用开发技能无疑打开了一扇通往创新世界的大门。对于初学者来说,了解并学习如何从无到有构建一个安卓应用是至关重要的第一步。本文将为你提供一份详尽的入门指南,帮助你理解安卓开发的基础知识,并通过实际示例引导你完成第一个简单的应用项目。无论你是编程新手还是希望扩展你的技能集,这份指南都将是你宝贵的资源。
54 5
|
2月前
|
移动开发 Dart 搜索推荐
打造个性化安卓应用:从零开始的Flutter之旅
【10月更文挑战第20天】本文将引导你开启Flutter开发之旅,通过简单易懂的语言和步骤,让你了解如何从零开始构建一个安卓应用。我们将一起探索Flutter的魅力,实现快速开发,并见证代码示例如何生动地转化为用户界面。无论你是编程新手还是希望扩展技能的开发者,这篇文章都将为你提供价值。
|
2月前
|
调度 Android开发 开发者
构建高效Android应用:探究Kotlin多线程优化策略
【10月更文挑战第11天】本文探讨了如何在Kotlin中实现高效的多线程方案,特别是在Android应用开发中。通过介绍Kotlin协程的基础知识、异步数据加载的实际案例,以及合理使用不同调度器的方法,帮助开发者提升应用性能和用户体验。
51 4
|
2月前
|
编解码 Android开发 UED
构建高效Android应用:从内存优化到用户体验
【10月更文挑战第11天】本文探讨了如何通过内存优化和用户体验改进来构建高效的Android应用。介绍了使用弱引用来减少内存占用、懒加载资源以降低启动时内存消耗、利用Kotlin协程进行异步处理以保持UI流畅,以及采用响应式设计适配不同屏幕尺寸等具体技术手段。
51 2
|
2月前
|
XML 数据可视化 Android开发
Android应用界面
Android应用界面中的布局和控件使用,包括相对布局、线性布局、表格布局、帧布局、扁平化布局等,以及AdapterView及其子类如ListView的使用方法和Adapter接口的应用。
25 0
Android应用界面
|
2月前
|
Android开发
Android开发显示头部Bar的需求解决方案--Android应用实战
Android开发显示头部Bar的需求解决方案--Android应用实战
21 0