ActivityManagerService

前语

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

  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,我要找叫做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。假如有不知道的小伙伴能够检查下这篇文章 问个问题,请描述下Android体系的发动流程。

这儿的发动调用进程过于复杂,个人认为记这个调用流程没有任何意义。只需记住一些要害办法即可。 我尽量写的能让各位记住。或许咱们只记住要害办法以及终究成果亦可。

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进程

sequenceDiagram
SystemServer->>ActivityManagerService: startOtherServices
ActivityManagerService->>ActivityTaskManagerService:systemReady
ActivityTaskManagerService->>RootWindowContainer:resumeTopActivities
RootWindowContainer->>ActivityStartController:省掉......
ActivityStartController->>ActivityStarter:execute
ActivityStarter->>ActivityStack:省掉......
ActivityStack->>ActivityStackSupervisor:startSpecificActivity(冷发动和热发动)
ActivityStackSupervisor->>ActivityTaskManagerService:startProcessAsync
ActivityTaskManagerService->>ZygoteProcess:省掉......
ZygoteProcess->>ZygoteProcess:startViaZygote
ZygoteProcess->>ZygoteProcess:zygoteSendArgsAndGetResult:发送参数给zygote创立子进程一起回来子进程的相关成果
ZygoteProcess->>ZygoteProcess:attemptUsapSendArgsAndGetResult:将参数经过socket发送给zygote进程,告知zygote割裂出一个子进程,并回来子进程pid。

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不一致,导致两个进程后续的履行代码不一样。然后走向不同的人生。此处能够参考本系列的上篇文章AMS的来源,SystemServer的前世此生

终究子进程会调用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的全体的图解。

ActivityManagerService,给我启动个App瞅瞅呗

终究

终究,咱们再来看一下文章最开端的几个问题。是否就有了相应的答案呢。

期望各位喜爱的小伙伴,能够点个赞,点个重视。你们的赞和重视便是我的动力。感谢各位大大了。