ActivityManagerService,给我启动个App瞅瞅呗

前言

其实早在几年前,我就有一个疑问。

  1. 为什么我们的逻辑代码写在Activity中,在App启动后就会执行到它。
  2. 为什么第三方库的初始化要写在Application中,而它为什么执行顺序比Activity还要靠前。

如果您想搞清楚这些原因,那么本文可能会给你提供些许帮助。文章很长(虽然这不是我的初衷),建议感兴趣的同学,坚持读完。

文章中会出现很多类名和方法名,它们仅仅是方便记忆用的。我们不必去强行记住,只要记住一些关键点即可。回头把本文当作一个字典,有忘记的点再重新看一下就行。

另外:由于本文太长。因此只适合一些,对App启动流程不太了解的同学。如果是十分了解的同学,可以直接略过本文。

本文将会通过Launcher的启动,讲解AMS的创建过程,进程的分裂流程,以及我们是如何执行到Activity的onCreate方法的。

老规矩,阅读文章之前,让我们先看一下这几个问题:

  1. AMS是如何创建的,它运行在哪个进程之中。
  2. ATMS和AMS的功能是什么区别又是什么。
  3. ServiceManager的作用是什么。
  4. App进程如何分裂来的。
  5. 为什么我们App会执ActivityThread的main方法。
  6. 我们是如何执行Activity的onCreate方法的。

希望您可以在看完文章之后,回答出上面的问题。如果您觉得文章对您有帮助的话,可以点个赞,加个关注,方便回头查看本文。

下面我们正式开始。

1. AMS如何启动

我们先来聊一下AMS的创建过程。上一篇文章中已经讲了,如果看过上篇文章的可以直接略过本节。如果还没看上篇文章,可以通过这节简单了解下。

1.1 SystyemServer中的AMS

我们知道,在Android启动流程中,Zygote进程fork出了SystemServer进程。而SystemServer进程中先后开启了几十个服务,而这其中就包含了AMS进程和ATMS进程。具体代码如下:

public final class SystemServer {

   /**
    * 开启引导服务
    */
    private void startBootstrapServices(@NonNull TimingsTraceAndSlog t) {
        // Activity manager runs the show.

        // 创建ATMS,通过SystemServiceManager调用AMTS的start方法,并添加到ServiceManager中
        ActivityTaskManagerService atm = mSystemServiceManager.startService(
                ActivityTaskManagerService.Lifecycle.class).getService();

        // 创建AMS。并持有ATMS引用
        mActivityManagerService = ActivityManagerService.Lifecycle.startService(
                mSystemServiceManager, atm);

        // 让AMS 持有 SystemServer中的SSM的引用
        mActivityManagerService.setSystemServiceManager(mSystemServiceManager);

        // 让AMS 持有 SystemServer中的INSTALLER的引用
        mActivityManagerService.setInstaller(installer);

        // Set up the Application instance for the system process and get started.
        mActivityManagerService.setSystemProcess();
    }
}

1.2 AMS和ATMS

AMS的功能是管理四大组件。通过获取进程的ApplicationThread对象,从而跨进程通知App进程创建Application和Activity对象。 但是从Android10.0.之后。可能是Google开发人员,觉得AMS的功能过于繁杂,违反了单一职责,所以又建了一个ActivityTaskManagerService(ATMS)用来管理Activity。减轻AMS负担。可能为了保持接口一致性,又让AMS持有ATMS的引用。

这操作像不像公司中的你,一个人肩负重任,为了减轻你的负担,给你找了个小老弟把你俩分成一组,他会分担你的部分工作。同时这个小老弟的工作要向你报告。而你要把你俩的工作结果对你的上层报告。

1.3 ServiceManager服务大管家

这里要多讲一个类,叫做ServiceManager。这是由init进程启动而来的一个守护进程,它运行在用户空间。由于他的特殊作用是所有binder服务都要在这个ServiceManager进程进行注册,所以它又被称作Binder服务大管家

说他是大管家是由于,我们都知道,为了App进程的安全性,所以进程与进程之间正常是无法互相访问的。如果想要互相访问,就要通过跨进程通信,在Android中最常见的跨进程通信就是BinderSocket共享内存等。但出于性能和安全性考虑,Binder成了Android官方推出的跨进程通信机制。

而由于进程和进程之间都互相不认识,所以就需要个介绍人,这个介绍人就是ServiceManager。有点类似于我们找工作,会把我们的个人信息投递到第三方平台,而公司招聘也会去第三方平台。这里的ServiceManager就相当于第三方平台。我们的AMS,会通过 ServiceManager.addService(Context.ACTIVITY_SERVICE, this); 告诉ServiceManager。如果有人想要找我,就只需要报出我的艺名Context.ACTIVITY_SERVICE 就行。而别的进程要是找AMS,就要找ServiceManager,调用它的getService(Context.ACTIVITY_SERVICE) 方法。ServiceManager就会将AMS的对象返回给那个进程。从而实现跨进程通信。

public final class ServiceManager {
    @UnsupportedAppUsage
    // 注意,这里的service都是IBinder对象,AMS,ATMS等都是IBinder对象。
    public static void addService(String name, IBinder service) {
        addService(name, service, false, IServiceManager.DUMP_FLAG_PRIORITY_DEFAULT);
    }

    @UnsupportedAppUsage
    public static void addService(String name, IBinder service, boolean allowIsolated) {
        addService(name, service, allowIsolated, IServiceManager.DUMP_FLAG_PRIORITY_DEFAULT);
    }

   /**
    * 将service对像(IBinder对象),以name的名称存放到ServiceManager进程中
    */
    @UnsupportedAppUsage
    public static void addService(String name, IBinder service, boolean allowIsolated,
            int dumpPriority) {
        try {
            getIServiceManager().addService(name, service, allowIsolated, dumpPriority);
        } catch (RemoteException e) {
            Log.e(TAG, "error in addService", e);
        }
    }

   /**
    * 获取ServiceManager进程Binder对象
    */
    private static IServiceManager getIServiceManager() {
        if (sServiceManager != null) {
            return sServiceManager;
        }

        sServiceManager = SereManagerNative
                .asInterface(Binder.allowBlocking(BinderInternal.getContextObject()));
        return sServiceManager;
    }

    /**
     * 通过名称返回IBinder对象
     */
    @UnsupportedAppUsage
    public static IBinder getService(String name) {
        try {
            IBinder service = sCache.get(name);
            if (service != null) {
                return service;
            } else {
                return Binder.allowBlocking(rawGetService(name));
            }
        } catch (RemoteException e) {
            Log.e(TAG, "error in getService", e);
        }
        return null;
    }

    /**
     * This is only intended to be called when the process is first being brought
     * up and bound by the activity manager. There is only one thread in the process
     * at that time, so no locking is done.
     *
     * @param cache the cache of service references
     * @hide
     */
    public static void initServiceCache(Map<String, IBinder> cache) {
        if (sCache.size() != 0) {
            throw new IllegalStateException("setServiceCache may only be called once");
        }
        sCache.putAll(cache);
    }
}

1.4 AMS设置系统相关服务

如下代码所示,设置系统常用进程至ServiceManger中。由于我们的AMS本身就是个继承自Binder的类。所以可以直接添加进ServiceManager。并且名称为Context.ACTIVITY_SERVICE。这里还有一些其他的Binder对象被添加到ServiceManager中,具体看代码即可。

另外ATMS也是通过类似的形式被加入到ServiceManager中。具体可以通过: ActivityTaskManagerService atm = mSystemServiceManager.startService( ActivityTaskManagerService.Lifecycle.class).getService(); 查看到相关代码。

public class ActivityManagerService extends IActivityManager.Stub{

    public void setSystemProcess() {
        try {
            // 将AMS添加到ServiceManager中,取名为Context.ACTIVITY_SERVICE
            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, /* allowIsolated= */ true,
                    DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PRIORITY_NORMAL | DUMP_FLAG_PROTO);

            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
            // 添加MemBinder
            ServiceManager.addService("meminfo", new MemBinder(this), /* allowIsolated= */ false,
                    DUMP_FLAG_PRIORITY_HIGH);

            // 添加GraphicsBinder
            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
            // 添加DbBinder
            ServiceManager.addService("dbinfo", new DbBinder(this));
            if (MONITOR_CPU_USAGE) {
                // 添加CpuBinder
                ServiceManager.addService("cpuinfo", new CpuBinder(this),
                        /* allowIsolated= */ false, DUMP_FLAG_PRIORITY_CRITICAL);
            }
            // 添加PermissionController
            ServiceManager.addService("permission", new PermissionController(this));
            // 添加ProcessInfoService
            ServiceManager.addService("processinfo", new ProcessInfoService(this));
            // 添加CacheBinder
            ServiceManager.addService("cacheinfo", new CacheBinder(this));

            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
                    "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());

            synchronized (this) {
                ProcessRecord app = mProcessList.newProcessRecordLocked(info, info.processName,
                        false,
                        0,
                        new HostingRecord("system"));
                app.setPersistent(true);
                app.pid = MY_PID;
                app.getWindowProcessController().setPid(MY_PID);
                app.maxAdj = ProcessList.SYSTEM_ADJ;
                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
                addPidLocked(app);
                mProcessList.updateLruProcessLocked(app, false, null);
                updateOomAdjLocked(OomAdjuster.OOM_ADJ_REASON_NONE);
            }
        } catch (PackageManager.NameNotFoundException e) {
            throw new RuntimeException(
                    "Unable to find android system package", e);
        }
    }
}

1.5 注意事项

这里需要注意几点:

  1. AMS和ATMS等都不是单独的进程,而是运行在SystemServer进程中的。
  2. ServiceManager添加的对象是IBinder对象,是用来跨进程通信的。
  3. AMS和ATMS可以通过ServiceManager获取。从而实现APP进程和SystemServer之间的通信。

2. AMS启动Launcher之旅

Android系统最后会启动一个Launcher的App。

从am这里的启动调用过程过于复杂,个人认为记这个调用流程没有任何意义。只要记住一些关键方法即可。 我尽量写的能让各位记住。或者大家只记住关键方法以及最后结果亦可。

2.1 systemReady()

SystemServer进程的startOtherServices中。通过AMSsystemReady方法。开始创建Launcher进程之旅。具体代码如下所示:

public final class SystemServer {
   /**
    * 开启其他服务
    */
    private void startOtherServices(@NonNull TimingsTraceAndSlog t) {

        // 创建IMS
        inputManager = new InputManagerService(context);

        // 创建WMS
        wm = WindowManagerService.main(context, inputManager, !mFirstBoot, mOnlyCore,
                new PhoneWindowManager(), mActivityManagerService.mActivityTaskManager);

        // IMS 添加到 ServiceManager
        ServiceManager.addService(Context.WINDOW_SERVICE, wm, /* allowIsolated= */ false,
                DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PROTO);

        // WMS 添加到 ServiceManager
        ServiceManager.addService(Context.INPUT_SERVICE, inputManager,
                /* allowIsolated= */ false, DUMP_FLAG_PRIORITY_CRITICAL);

        // 启动systemReady,开始启动launcher之旅
        mActivityManagerService.systemReady(() -> {}
    }
}

2.2 创建Launcher进程

下图是SystemServer通过AMS创建Luancher进程的关键方法的时序图

这里我们只记住关键方法即可。此处的时序图只是方便我们理解和查询的。

要注意,这个时序图的作用只是告诉大家,SystemServer进程中如何通过SocketZygote进程进行通信。从而分裂出一个App进程

2.2 热启动?or 冷启动?

启动App的关键方法之一就是ActivityStackSupervisorstartSpecificActivity方法。这里存在另外两个极其重要的方法。一个是realStartActivityLocked,另一个是startProcessAsync

startSpecificActivity方法中会判断进程是否存在,如果启动的APP进程已经存在,则调用realStartActivityLocked

如果不存在,则调用ATMSstartProcessAsync() 方法,先启动进程。

进程存在的启动方式就是热启动realStartActivityLocked();

进程不存在的启动方式就是冷启动startProcessAsync();

由于Launcher还没有创建,所以此处执行的是冷启动。而realStartActivityLocked后面将会进行讲解。

public class ActivityStackSupervisor{
    
    
    final ActivityTaskManagerService mService;
    // 通过热启动或者冷启动,启动APP
    void startSpecificActivity(ActivityRecord r, boolean andResume, boolean checkConfig) {
    
    
        // Is this activity's application already running?
        final WindowProcessController wpc =
                mService.getProcessController(r.processName, r.info.applicationInfo.uid);

        boolean knownToBeDead = false;
        if (wpc != null && wpc.hasThread()) {
    
    
            try {
    
    
                // 进程存在,热启动。在已经存在的进程中执行后续代码
                realStartActivityLocked(r, wpc, andResume, checkConfig);
                return;
            } catch (RemoteException e) {
    
    
                Slog.w(TAG, "Exception when starting activity "
                        + r.intent.getComponent().flattenToShortString(), e);
            }

            // If a dead object exception was thrown -- fall through to
            // restart the application.
            knownToBeDead = true;
        }

        final boolean isTop = andResume && r.isTopRunningActivity();
        // 进程不存在,冷启动。创建新的进程
        // 此处的mService是ATMS
        mService.startProcessAsync(r, knownToBeDead, isTop, isTop ? "top-activity" : "activity");
    }
}

2.3 ATMS准备创建新进程

通过ATMS启动进程,最终会调用ZygoteProcess类。该类会填写新进程的具体参数。

startViaZygote方法中,processClass为要启动main方法的类名,niceName是fork出的新进程的进程名。

通过Socket传递给Zygote进程,同时将Zygote进程中创建的子进程的pid返回给该进程中。通过返回进程的pid,来区分是Zygote进程还是子进程。

具体看下面代码中的注释。没有想象中的复杂。

public class ZygoteProcess {

    /**
     * Starts a new process via the zygote mechanism.
     *
     * @param processClass Class name whose static main() to run
     * @param niceName 'nice' process name to appear in ps
     * @return An object that describes the result of the attempt to start the process.
     * @throws ZygoteStartFailedEx if process start failed for any reason
     */
    private Process.ProcessStartResult startViaZygote(@NonNull final String processClass,
                                                      @Nullable final String niceName,
                                                      final int uid, final int gid,
                                                      @Nullable final int[] gids,
                                                      int runtimeFlags, int mountExternal,
                                                      int targetSdkVersion,
                                                      @Nullable String seInfo,
                                                      @NonNull String abi,
                                                      @Nullable String instructionSet,
                                                      @Nullable String appDataDir,
                                                      @Nullable String invokeWith,
                                                      boolean startChildZygote,
                                                      @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[] extraArgs)
                                                      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");
        } else if (mountExternal == Zygote.MOUNT_EXTERNAL_READ) {
            argsForZygote.add("--mount-external-read");
        } else if (mountExternal == Zygote.MOUNT_EXTERNAL_WRITE) {
            argsForZygote.add("--mount-external-write");
        } else if (mountExternal == Zygote.MOUNT_EXTERNAL_FULL) {
            argsForZygote.add("--mount-external-full");
        } else if (mountExternal == Zygote.MOUNT_EXTERNAL_INSTALLER) {
            argsForZygote.add("--mount-external-installer");
        } else if (mountExternal == Zygote.MOUNT_EXTERNAL_LEGACY) {
            argsForZygote.add("--mount-external-legacy");
        } else if (mountExternal == Zygote.MOUNT_EXTERNAL_PASS_THROUGH) {
            argsForZygote.add("--mount-external-pass-through");
        } else if (mountExternal == Zygote.MOUNT_EXTERNAL_ANDROID_WRITABLE) {
            argsForZygote.add("--mount-external-android-writable");
        }

        argsForZygote.add("--target-sdk-version=" + targetSdkVersion);

        if (niceName != null) {
            argsForZygote.add("--nice-name=" + niceName);
        }

        if (seInfo != null) {
            argsForZygote.add("--seinfo=" + seInfo);
        }

        if (instructionSet != null) {
            argsForZygote.add("--instruction-set=" + instructionSet);
        }

        if (appDataDir != null) {
            argsForZygote.add("--app-data-dir=" + appDataDir);
        }

        if (invokeWith != null) {
            argsForZygote.add("--invoke-with");
            argsForZygote.add(invokeWith);
        }

        if (startChildZygote) {
            argsForZygote.add("--start-child-zygote");
        }

        if (packageName != null) {
            argsForZygote.add("--package-name=" + packageName);
        }

        if (isTopApp) {
            argsForZygote.add(Zygote.START_AS_TOP_APP_ARG);
        }

        if (bindMountAppStorageDirs) {
            argsForZygote.add(Zygote.BIND_MOUNT_APP_STORAGE_DIRS);
        }

        if (bindMountAppsData) {
            argsForZygote.add(Zygote.BIND_MOUNT_APP_DATA_DIRS);
        }
        // 将会用行processClass这个类的main方法
        argsForZygote.add(processClass);

        if (extraArgs != null) {
            Collections.addAll(argsForZygote, extraArgs);
        }

        synchronized(mLock) {
            // openZygoteSocketIfNeeded 开启socket,准备socket通信
            // argsForZygote就是传递给Zygote进程,要启动的新进程的相关参数
            return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi),
                                              zygotePolicyFlags,
                                              argsForZygote);
        }
    }

    /**
     * Sends an argument list to the zygote process, which starts a new child
     * and returns the child's pid. 
     */

    private Process.ProcessStartResult zygoteSendArgsAndGetResult(
            ZygoteState zygoteState, int zygotePolicyFlags, @NonNull ArrayList<String> args)
            throws ZygoteStartFailedEx {
        // 将新进程的相关参数args,写入到msgStr中
        String msgStr = args.size() + "\n" + String.join("\n", args) + "\n";
        // 传递 msgStr
        return attemptZygoteSendArgsAndGetResult(zygoteState, msgStr);
    }

    // socket 传递数据。返回新进程相关结果
    private Process.ProcessStartResult attemptUsapSendArgsAndGetResult(
            ZygoteState zygoteState, String msgStr)
            throws ZygoteStartFailedEx, IOException {
        try (LocalSocket usapSessionSocket = zygoteState.getUsapSessionSocket()) {
            final BufferedWriter usapWriter =
                    new BufferedWriter(
                            new OutputStreamWriter(usapSessionSocket.getOutputStream()),
                            Zygote.SOCKET_BUFFER_SIZE);
            final DataInputStream usapReader =
                    new DataInputStream(usapSessionSocket.getInputStream());
            // 写入新进程的args参数
            usapWriter.write(msgStr);
            // 刷新数据
            usapWriter.flush();

            Process.ProcessStartResult result = new Process.ProcessStartResult();
            // 获取创建出的新进程的pid
            result.pid = usapReader.readInt();

            if (result.pid >= 0) {
            // 返回新进程的相关结果
                return result;
            } else {
                throw new ZygoteStartFailedEx("USAP specialization failed");
            }
        }
    }
}

3. 重回Zygote

3.1 大致流程

这里会先讲解下大体流程,让各位有些印象。方便理解后面代码。

  1. Zygote进程会执行runSelectLoop方法,其内部是一个while(true)循环, 正常情况下会执行Os.poll(pollFDs, pollTimeoutMs); 使Zygote进程进入休眠
  2. 当接收到分裂进程的消息时,Zygote该进程会被唤醒。通过Zygote.forkAndSpecialize分裂进程。
  3. 两个进程通过返回pid的不同(子进程返回pid为0,Zygote进程返回pid为子进程的pid),执行不同的代码。
  4. 子进程跳出while循环,通过反射执行ActivityThreadmain方法。
  5. Zygote 进程会再次进入while(true)循环中,执行Os.poll(pollFDs, pollTimeoutMs); 使进程进入休眠,直到下次分裂进程。

3.2 Zygote循环

先看下ZygoteServer中的runSelectLoop() 方法。 该方法内部的Os.poll(pollFDs, pollTimeoutMs); 会使Zygote进程休眠ZygoteConnection.processOneCommand() 方法会执行分裂进程的方法。

具体代码如下:

/**
 * Server socket class for zygote processes.
 */
class ZygoteServer {

    /**
     * Set by the child process, immediately after a call to {@code Zygote.forkAndSpecialize}.
     */
    private boolean mIsForkChild;

    void setForkChild() {
        mIsForkChild = true;
    }

    /**
     * Runs the zygote process's select loop. Accepts new connections as
     * they happen, and reads commands from connections one spawn-request's
     * worth at a time.
     */
    Runnable runSelectLoop(String abiList) {
        ArrayList<FileDescriptor> socketFDs = new ArrayList<>();
        ArrayList<ZygoteConnection> peers = new ArrayList<>();

        while (true) {
            int[] usapPipeFDs = null;
            StructPollfd[] pollFDs;

            int pollReturnValue;
            try {
                // 此处进行进程休眠
                pollReturnValue = Os.poll(pollFDs, pollTimeoutMs);
            } catch (ErrnoException ex) {
                throw new RuntimeException("poll failed", ex);
            }

            if (pollReturnValue == 0) {
                // 代码省略......
            } else {
                boolean usapPoolFDRead = false;

                while (--pollIndex >= 0) {
                    if (pollIndex == 0) {
                        // Zygote server socket
                        // 代码省略......

                    } else if (pollIndex < usapPoolEventFDIndex) {
                        // Session socket accepted from the Zygote server socket
                        try {
                            ZygoteConnection connection = peers.get(pollIndex);
                            // processOneCommand方法中会分裂出子进程。
                            // 子进程会调用setForkChild将mIsForkChild设置为true
                            final Runnable command = connection.processOneCommand(this);

                            // 子进程mIsForkChild为true
                            if (mIsForkChild) {
                                return command;
                            } else {
                                // 代码省略......
                            }
                        } catch (Exception e) {
                             // 异常处理,省略......

                        } finally {
                            // Reset the child flag

                            mIsForkChild = false;
                        }
                    } else {
                      // 代码省略......
                    }
                }
            }
        }
    }
}

3.3 Fork进程

Zygote进程fork出新的进程。同时通过返回的pid的区别,来区分新进程Zygote进程

由于pid值不一致,导致两个进程后续的执行代码不一样。从而走向不同的人生。

最终子进程会调用RuntimeInit.findStaticMain() 方法,通过反射执行ActivityThreadmain方法。

这就是为什么我们App是从Activity的main方法启动的。

/**
 * A connection that can make spawn requests.
 */
class ZygoteConnection {
    /**
     * 返回一个Runnable,内容为fork子进程。
     * zygote进程此处返回的pid为子进程pid,该方法返回值为null
     * 子进程,返回的pid为0,该方法返回handleChildProc方法的返回值
     */
    Runnable processOneCommand(ZygoteServer zygoteServer) {
        // 读取传给Zygote进程的参数列表
        String[] args = Zygote.readArgumentList(mSocketReader);
        ZygoteArguments parsedArgs = new ZygoteArguments(args);

        // 通过native方法fork出进程。
        // zygote进程的pid为子进程的pid。
        // fork出的子进程的pid为0
        int 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);

        try {
            if (pid == 0) {
                // 子进程中的ZygoteServer的mIsForkChild设置为true
                zygoteServer.setForkChild();
                // 子进程关闭socket
                zygoteServer.closeServerSocket();

                // 处理子进程,内部会通过反射调用ActivityThread的main方法
                return handleChildProc(parsedArgs, childPipeFd, parsedArgs.mStartChildZygote);
            } else {
                return null;
            }
        } 
    }
    // 处理子进程
    private Runnable handleChildProc(ZygoteArguments parsedArgs,
            FileDescriptor pipeFd, boolean isZygote) {
        // 设置进程名称
        Zygote.setAppProcessName(parsedArgs, TAG);

        // 这里会通过反射,调用ActivityThread的main方法
        return ZygoteInit.childZygoteInit(parsedArgs.mTargetSdkVersion,
                        parsedArgs.mRemainingArgs, null /* classLoader */);
    }
}

4. 新的进程,新的人生

4.1 ActivityThread类

新的进程中会执行ActivityThreadmain方法。创建Looper。执行attach方法,最终执行Looper.loop(); 进入循环等待。

这里注意,在attach方法中,会通过ServiceManager获取AMS服务。从而将ApplicationThread传递给AMS,以方便实现跨进程通信。

这里要提出一点,ApplicationThread对象子进程AMS实现跨进程通信的重要对象。子进程将ApplicationThread对象传递给AMSAMS会调用传递来的ApplicationThread对象来让子进程执行一些方法。

public final class ActivityThread {
    private final ResourcesManager mResourcesManager;
    @UnsupportedAppUsage
    ActivityThread() {
        mResourcesManager = ResourcesManager.getInstance();
    }

    public static void main(String[] args) {
        // 准备looper
        Looper.prepareMainLooper();
        // 创建ActivityThread对象
        ActivityThread thread = new ActivityThread();
        // attach方法
        thread.attach(false, startSeq);

        // 执行loop,等待handler传递消息
        Looper.loop();
    }

    // binder对象,用来跨进程通信
    final ApplicationThread mAppThread = new ApplicationThread();

    @UnsupportedAppUsage
    private void attach(boolean system, long startSeq) {
        sCurrentActivityThread = this;
        mSystemThread = system;
        if (!system) {
            // 此处获取AMS的binder实例,用来跨进程通信
            final IActivityManager mgr = ActivityManager.getService();
            try {
                // 跨进程通信,将mAppThread,传给AMS
                mgr.attachApplication(mAppThread, startSeq);
            } catch (RemoteException ex) {
                throw ex.rethrowFromSystemServer();
            }
        } else {
            // SystemServer中执行的代码,此处省略......
    }
}

4.2 AMS跨进程通信

由于在attach方法中执行mgr.attachApplication方法。 mgr是AMS实例。所以该方法会跨进程通信,将mAppThread传递给AMS

同时执行从子进程传递来的ApplicationThread类中的bindApplication方法。该方法会在子进程中创建Application对象,并执行它的onCreate方法。

而下方的mAtmInternal.attachApplication这句代码,会在ATMS中跨进程通信,通知子进程创建Activity对象,并执行它的onCreate方法。

具体代码如下:

public class ActivityManagerService extends IActivityManager.Stub{
    @Override
    public final void attachApplication(IApplicationThread thread, long startSeq) {
        synchronized (this) {
            int callingPid = Binder.getCallingPid();
            final int callingUid = Binder.getCallingUid();
            final long origId = Binder.clearCallingIdentity();

            // 调用attachApplicationLocked方法
            attachApplicationLocked(thread, callingPid, callingUid, startSeq);
        }
    }

    @GuardedBy("this")
    private boolean attachApplicationLocked(@NonNull IApplicationThread thread,
            int pid, int callingUid, long startSeq) {
            // 代码省略......

            // 此处跨进程调用调用App进程中的ApplicatioThread的bindApplication方法
            // 在App进程中,创建Applicaiton,执行onCreate方法
            thread.bindApplication(processName, appInfo, providerList,
                    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,
                    app.mDisabledCompatChanges);

            // See if the top visible activity is waiting to run in this process...
            if (normalMode) {
                // 执行,ATMS的attachApplicaiton方法,
                // 跨进程调用,调用App进程的ActivitThread对象的attachApplicaiton方法
                //创建Acitivity执行onCreate方法
                boolean didSomething = mAtmInternal.attachApplication(app.getWindowProcessController());
            }

        return true;
    }
}

4.3 创建Application

这里会通过上面代码中的thread.bindApplication 跨进程通信。调用ActivityThread的内部类 ApplicationThreadbindApplication方法。
最终在子进程中创建Application,执行ApplicationonCreate方法。

具体如下面代码所示:

public final class ActivityThread extends ClientTransactionHandler {
    Application mInitialApplication;
    final H mH = new H();

    private class ApplicationThread extends IApplicationThread.Stub {
        @Override
        public final void bindApplication(String processName, ApplicationInfo appInfo,...) {
            AppBindData data = new AppBindData();
            data.processName = processName;
            data.appInfo = appInfo;

            // 调用 Handler
            sendMessage(H.BIND_APPLICATION, data);
        }
    }

    class H extends Handler {
        public static final int BIND_APPLICATION = 110;
        @UnsupportedAppUsage
        public static final int EXIT_APPLICATION = 111;

        public void handleMessage(Message msg) {
            switch (msg.what) {
                case BIND_APPLICATION:
                    AppBindData data = (AppBindData)msg.obj;
                    handleBindApplication(data);
                    break;
                case EXIT_APPLICATION:
                    if (mInitialApplication != null) {
                        mInitialApplication.onTerminate();
                    }
                    Looper.myLooper().quit();
                    break;
           }
        }
    }

    @UnsupportedAppUsage
    private void handleBindApplication(AppBindData data) {
        Application app;
        // data.inf是LoadApk对象。创建application对象
        app = data.info.makeApplication(data.restrictedBackupMode, null);
        mInitialApplication = app;
        // 执行,Application的onCreate方法
        mInstrumentation.callApplicationOnCreate(app);
    }
}

4.4 创建Activity

通过ATMS中的attachApplication方法。会通过执行ActivityStackSupervisorrealStartActivityLocked方法。

此处会通过ClientTransaction以及ClientLifecycleManager等类的流转,最终会调用ActivityThread中的handleLaunchActivity 方法。对ClientTransactionClientLifecycleManager如何执行事件流转的同学,可以进源码中查看。此处只说结论,那就是,又再次跨进程通信,让App进程调ActivityThread的handleLaunchActivity方法。

public class ActivityStackSupervisor{
    boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
            boolean andResume, boolean checkConfig) throws RemoteException {
            // Create activity launch transaction.
            final ClientTransaction clientTransaction = ClientTransaction.obtain(
                        proc.getThread(), r.appToken);
            // 对应ActivityThread中的 handleLaunchActivity 方法
            clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),省略......));

           // 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);

           return true;
    }
}

handleLaunchActivity最后会调用performLaunchActivity方法。内部创建了Activity对象,同时执行了attachonCreate方法,并且设置了主题等操作。具体如下图代码。

public final class ActivityThread extends ClientTransactionHandler {
    @Override
    public Activity handleLaunchActivity(ActivityClientRecord r,
            PendingTransactionActions pendingActions, Intent customIntent) {

        final Activity a = performLaunchActivity(r, customIntent);
        return a;
    }

    /**  Core implementation of activity launch. */
    private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
        ActivityInfo aInfo = r.activityInfo;
        ContextImpl appContext = createBaseContextForActivity(r);
        Activity activity = null;
        try {
            java.lang.ClassLoader cl = appContext.getClassLoader();
            activity = mInstrumentation.newActivity(
                    cl, component.getClassName(), r.intent);

        } catch (Exception e) {
            if (!mInstrumentation.onException(activity, e)) {
                throw new RuntimeException(
                    "Unable to instantiate activity " + component
                    + ": " + e.toString(), e);
            }
        }

        try {
            // 由于bindApplication已经创建过application
            // 所以此处返回,前文中创建的application
            Application app = r.packageInfo.makeApplication(false, mInstrumentation);

            if (activity != null) {
                CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
                Configuration config = new Configuration(mCompatConfiguration);
                if (r.overrideConfig != null) {
                    config.updateFrom(r.overrideConfig);
                }

                // Activity resources must be initialized with the same loaders as the
                // application context.
                appContext.getResources().addLoaders(
                        app.getResources().getLoaders().toArray(new ResourcesLoader[0]));

               // attach 方法
                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);

                // 设置主题
                int theme = r.activityInfo.getThemeResource();
                if (theme != 0) {
                    activity.setTheme(theme);
                }

                // 执行onCreate方法
                if (r.isPersistable()) {
                    mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
                } else {
                    mInstrumentation.callActivityOnCreate(activity, r.state);
                }

            }
            r.setState(ON_CREATE);

        } catch (SuperNotCalledException e) {
            throw e;

        } catch (Exception e) {
            if (!mInstrumentation.onException(activity, e)) {
                throw new RuntimeException(
                    "Unable to start activity " + component
                    + ": " + e.toString(), e);
            }
        }

        return activity;
    }
}

至此,一个App的启动过程就讲完了。

  1. 从最初的通知zygote创建子进程,在子进程中执行ActivityThread 的main方法。
  2. 再到,将applicationThread对象传递给AMS,调用AMS的attachApplication方法。
  3. 再在AMS进程中调用bindApplicaiton让子进程创建application对象。
  4. 以及通过ClientLifecycleManager和ClientTransaction来执行,子进程中的handleLaunchActivity方法,最终调用performLaunchActivity方法来创建activity对象,执行activity的onCreate方法。

5. 整体流程

下图为Zygote进程从fork出SystemServer到创建子进程的activity的整体的图解。

《Framework 核心知识点汇总手册》

Handler 机制实现原理部分
1.宏观理论分析与Message源码分析
2.MessageQueue的源码分析
3.Looper的源码分析
4.handler的源码分析
5.总结

Binder 原理

1.学习Binder前必须要了解的知识点
2.ServiceManager中的Binder机制
3.系统服务的注册过程
4.ServiceManager的启动过程
5.系统服务的获取过程
6.Java Binder的初始化
7.Java Binder中系统服务的注册过程

Zygote

  1. Android系统的启动过程及Zygote的启动过程
  2. 应用进程的启动过程

AMS源码分析

  1. Activity生命周期管理
  2. onActivityResult执行过程
  3. AMS中Activity栈管理详解

深入PMS源码

1.PMS的启动过程和执行流程
2.APK的安装和卸载源码分析
3.PMS中intent-filter的匹配架构

WMS
1.WMS的诞生
2.WMS的重要成员和Window的添加过程
3.Window的删除过程

《Android Framework学习手册》:

  1. 开机Init 进程
  2. 开机启动 Zygote 进程
  3. 开机启动 SystemServer 进程
  4. Binder 驱动
  5. AMS 的启动过程
  6. PMS 的启动过程
  7. Launcher 的启动过程
  8. Android 四大组件
  9. Android 系统服务 - Input 事件的分发过程
  10. Android 底层渲染 - 屏幕刷新机制源码分析
  11. Android 源码分析实战

每个知识点都有左侧导航书签页,看的时候十分方便,由于内容较多,这里就截取一部分图吧。需要的读者朋友们可以进行参考:https://0a.fit/acnLL

《Android 进阶面试指南》

猜你喜欢

转载自blog.csdn.net/m0_64420071/article/details/128373710