likes
comments
collection
share

ActivityManagerService,给我启动个App瞅瞅呗

作者站长头像
站长
· 阅读数 78

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

SystemServerActivityManagerServiceActivityTaskManagerServiceRootWindowContainerActivityStartControllerActivityStarterActivityStackActivityStackSupervisorZygoteProcessstartOtherServicessystemReadyresumeTopActivities省略......execute省略......startSpecificActivity(冷启动和热启动)startProcessAsync省略......startViaZygotezygoteSendArgsAndGetResult:发送参数给zygote创建子进程同时返回子进程的相关结果attemptUsapSendArgsAndGetResult:将参数通过socket发送给zygote进程,通知zygote分裂出一个子进程,并返回子进程pid。SystemServerActivityManagerServiceActivityTaskManagerServiceRootWindowContainerActivityStartControllerActivityStarterActivityStackActivityStackSupervisorZygoteProcess

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瞅瞅呗

最后

最后,我们再来看一下文章最开始的几个问题。是否就有了相应的答案呢。

希望各位喜欢的小伙伴,可以点个赞,点个关注。你们的赞和关注就是我的动力。感谢各位大大了。

转载自:https://juejin.cn/post/7178437969622564924
评论
请登录