Activity之应用进程创建流程简析

本所引用的代码为Android 6.0版本

请尊重博主劳动成果,转载请标明出处。

一 ZygoteInit进程

本文从Java的文件来分析ZygotInit创建流程。如果想从linux和底层C/C++来分析,可以阅读底部的参考博客。

/android-6.0.0_r1/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

1,首先调用main方法:

    public static void main(String argv[]) {
        try {
            ...
            boolean startSystemServer = false;
            String socketName = "zygote";
            String abiList = null;
            ...

            //创建LocalServerSocket,用来接收创建进程的请求和通信
            registerZygoteSocket(socketName);
            ...
            //执行预加载
            preload();

            ...

            if (startSystemServer) {
  //创建系统服务进程
                startSystemServer(abiList, socketName);
            }

            Log.i(TAG, "Accepting command socket connections");
            //接收Socket连接并处理相应请求
            runSelectLoop(abiList);

            //关闭ServerSocket,即ZygoteInit进程退出
            closeServerSocket();
        } catch (MethodAndArgsCaller caller) {
            //调用该异常的run方法
            caller.run();
        } catch (RuntimeException ex) {
            Log.e(TAG, "Zygote died with exception", ex);
            closeServerSocket();
            throw ex;
        }
    }

获取系统abi(Android Binary Interface)列表,创建ServerSocket。接着创建系统服务进程,完成之后便无限循环接收Socket连接和处理请求信息。于是Zygote进程便创建了。Zygote进程主要是用来fork创建VM。

2,创建LocalServerSocket的registerZygoteSocket()方法代码:

    private static void registerZygoteSocket(String socketName) {
        if (sServerSocket == null) {
            int fileDesc;
            //ANDROID_SOCKET_PREFIX为"ANDROID_SOCKET_",socketName为“zygote”
            final String fullSocketName = ANDROID_SOCKET_PREFIX + socketName;
            try {
                String env = System.getenv(fullSocketName);
                fileDesc = Integer.parseInt(env);
            } catch (RuntimeException ex) {
                throw new RuntimeException(fullSocketName + " unset or invalid", ex);
            }

            try {
                FileDescriptor fd = new FileDescriptor();
                fd.setInt$(fileDesc);
                sServerSocket = new LocalServerSocket(fd);
            } catch (IOException ex) {
                throw new RuntimeException(
                        "Error binding to local socket '" + fileDesc + "'", ex);
            }
        }
    }

创建LocalServerSocket服务,它会一直接收Socket链接,并对Socket发送过来的信息进行处理,即创建相应的进程。

3,preload()方法代码:

    static void preload() {
        Log.d(TAG, "begin preload");
        //加载class
        preloadClasses();
        //加载资源
        preloadResources();
        //加载OpenGL相关的资源
        preloadOpenGL();
        //加载公共的so文件
        preloadSharedLibraries();
        //加载文字相关的资源
        preloadTextResources();
        // Ask the WebViewFactory to do any initialization that must run in the zygote process,
        // for memory sharing purposes.
        //创建WebView进程,即Chromium进程
        WebViewFactory.prepareWebViewInZygote();
        Log.d(TAG, "end preload");
    }

preload()方法会加载系统运行所需的基本资源和文件。

4,runSelectLoop()方法代码:

    private static void runSelectLoop(String abiList) throws MethodAndArgsCaller {
        ArrayList<FileDescriptor> fds = new ArrayList<FileDescriptor>();
        ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>();

        fds.add(sServerSocket.getFileDescriptor());
        peers.add(null);

        //无限循环接收连接
        while (true) {
            StructPollfd[] pollFds = new StructPollfd[fds.size()];
            for (int i = 0; i < pollFds.length; ++i) {
                pollFds[i] = new StructPollfd();
                pollFds[i].fd = fds.get(i);
                pollFds[i].events = (short) POLLIN;
            }
            try {
                Os.poll(pollFds, -1);
            } catch (ErrnoException ex) {
                throw new RuntimeException("poll failed", ex);
            }
            for (int i = pollFds.length - 1; i >= 0; --i) {
                if ((pollFds[i].revents & POLLIN) == 0) {
                    continue;
                }
                if (i == 0) {
                    ZygoteConnection newPeer = acceptCommandPeer(abiList);
                    peers.add(newPeer);
                    fds.add(newPeer.getFileDesciptor());
                } else {
                    //执行ZygoteConnection的runOnce()方法
                    boolean done = peers.get(i).runOnce();
                    //如果为true,则将ZygoteConnection对象从peers移除,
                    if (done) {
                        peers.remove(i);
                        fds.remove(i);
                    }
                }
            }
        }
    }

无限循环等等和接收Socket连接,并将获取的连接封装为ZygoteConnection对象,并将对象存入peers列表,只有执行结果为true的对象才将其从peers集合中移除。这种处理方式能够让执行失败的ZygoteConnection对象被循环处理。ZygoteConnection对象带有需要创建的进程信息和执行创建的方法。ZygoteConnection类将在下一节进行分析。

5,acceptCommandPeer()方法代码:

    private static ZygoteConnection acceptCommandPeer(String abiList) {
        try {
            return new ZygoteConnection(sServerSocket.accept(), abiList);
        } catch (IOException ex) {
            throw new RuntimeException(
                    "IOException during accept()", ex);
        }
    }

这个方法很简单,接收Socket链接,将收到的连接封装为ZygoteConnection对象。

Zygote进程创建成功,之后所有的应用进程都是从它fork而来。

二 创建应用进程

ActivityManagerService启动应用创建

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

应用进程由ActivityManagerService创建:
以点击桌面图标启动应用(假设该应用未启动过)为例,从startActivity开启,最终会调用到ActivityService的startProcessLocked()方法。
6,startProcessLocked()方法主要代码:

    private final void startProcessLocked(ProcessRecord app, String hostingType,
            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {

        ...

        try {
            ...

            boolean isActivityProcess = (entryPoint == null);
            //ActivityThread的类路径,使用反射来启用ActivityThread
            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
            ...
            //开始创建进程
            Process.ProcessStartResult startResult = Process.start(entryPoint,
                    app.processName, uid, uid, gids, debugFlags, mountExternal,
                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
                    app.info.dataDir, entryPointArgs);

        } catch (RuntimeException e) {
            ...
        }
        ...
    }

在startProcessLocked中会调用Process.start()方法来开启一个进程,该进程便是Activity运行的进程。

Process向ServerSocket发送参数信息

/android-6.0.0_r1/frameworks/base/core/java/android/os/Process.java

7,Process.start()方法代码:

    public static final ProcessStartResult start(final String processClass,
                                  final String niceName,
                                  int uid, int gid, int[] gids,
                                  int debugFlags, int mountExternal,
                                  int targetSdkVersion,
                                  String seInfo,
                                  String abi,
                                  String instructionSet,
                                  String appDataDir,
                                  String[] zygoteArgs) {
        try {
            return startViaZygote(processClass, niceName, uid, gid, gids,
                    debugFlags, mountExternal, targetSdkVersion, seInfo,
                    abi, instructionSet, appDataDir, zygoteArgs);
        } catch (ZygoteStartFailedEx ex) {
            ...
        }
    }

8,继续往下看,startViaZygote方法代码:

    private static ProcessStartResult startViaZygote(final String processClass,
                                  final String niceName,
                                  final int uid, final int gid,
                                  final int[] gids,
                                  int debugFlags, int mountExternal,
                                  int targetSdkVersion,
                                  String seInfo,
                                  String abi,
                                  String instructionSet,
                                  String appDataDir,
                                  String[] extraArgs)
                                  throws ZygoteStartFailedEx {
        synchr
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值