Skip to content

Latest commit

 

History

History
407 lines (355 loc) · 12.1 KB

应用程序进程启动过程.md

File metadata and controls

407 lines (355 loc) · 12.1 KB

1 简介

应用程序进程启动过程分为三步骤:

  • AMS 通过 socket 向 zygote 发送创建应用程序进程请求
  • zygote 接收请求并创建应用程序进程
  • 应用进程创建后会启动 Binder 线程池以及开启消息循环机制

2 源码

2.1 AMS 发送启动应用程序进程的请求

2.1.1 AMS#startProcessLocked()

AMS 通过调用 startProcessLocked() 向Zygote进程发送请求

private final void startProcessLocked(...) {
        ...
        try {
            try {
                final int userId = UserHandle.getUserId(app.uid);
                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
            } catch (RemoteException e) {
                throw e.rethrowAsRuntimeException();
            }
            //1.创建应用程序进程的用户ID   
            int uid = app.uid;
            int[] gids = null;
            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
            if (!app.isolated) {
              ...            
              // 2.对gids进行创建和赋值
                if (ArrayUtils.isEmpty(permGids)) {
                    gids = new int[2];
                } else {
                    gids = new int[permGids.length + 2];
                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
                }
                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
                ...
            }

           ...
            //3.entryPoint = "android.app.ActivityThread"
            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
            ...
            //4.调用Process的start函数 最终调用 startViaZygote
            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) {
          ...
        }
    }
   ...
    }

2.1.2 Process#startViaZygote()

private static ProcessStartResult startViaZygote(...)
                                  throws ZygoteStartFailedEx {
        synchronized(Process.class) {
            //1.字符串列表argsForZygote 保存启动应用进程的启动参数
            ArrayList<String> argsForZygote = new ArrayList<String>();
            argsForZygote.add("--runtime-args");
            argsForZygote.add("--setuid=" + uid);
            argsForZygote.add("--setgid=" + gid);
          ...
            if (gids != null && gids.length > 0) {
                StringBuilder sb = new StringBuilder();
                sb.append("--setgroups=");

                int sz = gids.length;
                for (int i = 0; i < sz; i++) {
                    if (i != 0) {
                        sb.append(',');
                    }
                    sb.append(gids[i]);
                }
                argsForZygote.add(sb.toString());
            }
         ...
            argsForZygote.add(processClass);
            if (extraArgs != null) {
                for (String arg : extraArgs) {
                    argsForZygote.add(arg);
                }
            }
            //应用进程的启动参数写入到 ZygoteState 中
            return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote);
        }
    }

2.1.3 Process#openZygoteSocketIfNeeded

private static ZygoteState openZygoteSocketIfNeeded(String abi) throws ZygoteStartFailedEx {
    if (primaryZygoteState == null || primaryZygoteState.isClosed()) {
        try {
            //1.名称为ZYGOTE_SOCKET(zygote)的Socket 建立连接 运行在 64 位Zygote进程
            primaryZygoteState = ZygoteState.connect(ZYGOTE_SOCKET);
        } catch (IOException ioe) {
            ...
        }
    }
    if (primaryZygoteState.matches(abi)) {
        return primaryZygoteState;
    }
    if (secondaryZygoteState == null || secondaryZygoteState.isClosed()) {
        try {
        //2.连接name为“zygote_secondary”的Socket 运行在 32 位Zygote进程
        secondaryZygoteState = ZygoteState.connect(SECONDARY_ZYGOTE_SOCKET);
        } catch (IOException ioe) {
           ...
        }
    }
    if (secondaryZygoteState.matches(abi)) {
        return secondaryZygoteState;
    }
    ...

2.1.4 ZygoteInit#main()

Socket 进行连接成功并匹配 abi 后会返回 ZygoteState 类型对象,Zygote 进程收到一个创建新的应用程序进程的请求,回头看看 ZygoteInit#main。

public static void main(String argv[]) {
       ...
        try {
         ...       
            //1.注册Zygote用的Socket
            registerZygoteSocket(socketName);
           ...
           //2.预加载类和资源
           preload();//2
           ...
            if (startSystemServer) {
            //3.启动SystemServer进程
                startSystemServer(abiList, socketName);
            }
            Log.i(TAG, "Accepting command socket connections");
            //4.等待客户端请求 这里收到请求
            runSelectLoop(abiList);
            closeServerSocket();
        } catch (MethodAndArgsCaller caller) {
            caller.run();
        } catch (RuntimeException ex) {
            Log.e(TAG, "Zygote died with exception", ex);
            closeServerSocket();
            throw ex;
        }
    }

2.1.5 ZygoteInit#runSelectLoop()

rivate static void runSelectLoop(String abiList) throws MethodAndArgsCaller {
        ...
        while (true) {
        ...
            for (int i = pollFds.length - 1; i >= 0; --i) {
                ..
                } else {
                    //调用ZygoteConnection的runOnce函数
                    boolean done = peers.get(i).runOnce();
                    if (done) {
                        peers.remove(i);
                        fds.remove(i);
                    }
                }
            }
        }
    }

2.1.6 ZygoteConnection#runOnce()

boolean runOnce() throws ZygoteInit.MethodAndArgsCaller {
        String args[];
        Arguments parsedArgs = null;
        FileDescriptor[] descriptors;
        try {
            //1.获取应用程序进程的启动参数
            args = readArgumentList();
            descriptors = mSocket.getAncillaryFileDescriptors();
        } catch (IOException ex) {
            ...
        }
        ...
        try {
            parsedArgs = new Arguments(args);
        ...
            //2.创建应用程序进程
            pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids,
                    parsedArgs.debugFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo,
                    parsedArgs.niceName, fdsToClose, parsedArgs.instructionSet,
                    parsedArgs.appDataDir);
        } catch (ErrnoException ex) {
          ....
        }
        //pid == 0 在新创建的子进程中执行的
        if (pid == 0) {
                // in child
                IoUtils.closeQuietly(serverPipeFd);
                serverPipeFd = null;
                //调用 handleChildProc 最终调用 RuntimeInit#zygoteInit
                handleChildProc(parsedArgs, descriptors, childPipeFd, newStderr);
                return true;
            } else {
                // in parent...pid of < 0 means failure
                IoUtils.closeQuietly(childPipeFd);
                childPipeFd = null;
                return handleParentProc(pid, descriptors, serverPipeFd, parsedArgs);
            }
      ...
    }

2.1.7 RuntimeInit#zygoteInit

public static final void zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
            throws ZygoteInit.MethodAndArgsCaller {
        if (DEBUG) Slog.d(TAG, "RuntimeInit: Starting application from zygote");
        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "RuntimeInit");
        redirectLogStreams();
        commonInit();
        //1.创建的应用程序进程中创建Binder线程池
        nativeZygoteInit();
        //2.通过反射来获得 android.app.ActivityThread 类
        applicationInit(targetSdkVersion, argv, classLoader);
    }

2.2 Binder线程池启动过程

应用程序进程创建过程中会启动Binder线程池以及在应用程序进程启动后会创建消息循环

2.2.1 RuntimeInit#zygoteInit()

  public static final void zygoteInit(...)
            throws ZygoteInit.MethodAndArgsCaller {
        ...
        //创建Binder线程池 是本地方法    
        nativeZygoteInit();
        applicationInit(targetSdkVersion, argv, classLoader);
    }

2.2.2 app_main.cpp#onZygoteInit()

nativeZygoteInit 是一个本地方法,到了 c 层

 virtual void onZygoteInit()
    {
        sp<ProcessState> proc = ProcessState::self();
        ALOGV("App process: starting thread pool.\n");
        //ProcessState#startThreadPool()
        proc->startThreadPool();
    }

2.2.3 ProcessState.cpp#startThreadPool()

void ProcessState::startThreadPool()
{
    AutoMutex _l(mLock);
    if (!mThreadPoolStarted) {//确保Binder线程池只会被启动一次
        mThreadPoolStarted = true;
        spawnPooledThread(true);
    }
}

2.2.4 ProcessState.cpp#spawnPooledThread()

void ProcessState::spawnPooledThread(bool isMain)
{
    if (mThreadPoolStarted) {
        String8 name = makeBinderThreadName();
        ALOGV("Spawning new pooled thread, name=%s\n", name.string());
        sp<Thread> t = new PoolThread(isMain);
        //启动一个新的线程
        t->run(name.string());
    }
}

2.2.5 ProcessState.cpp

//继承了Thread类
class PoolThread : public Thread
{
..
protected:
    virtual bool threadLoop()
    {   
        //当前线程注册到Binder驱动程序中
        IPCThreadState::self()->joinThreadPool(mIsMain);
        return false;
    }
    const bool mIsMain;
};

2.3 消息循环创建过程

RuntimeInit 的 invokeStaticMain(),代码如下所示。

2.3.1 RuntimeInit#invokeStaticMain

private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader)
        throws ZygoteInit.MethodAndArgsCaller {
    Class<?> cl;
  ...
    throw new ZygoteInit.MethodAndArgsCaller(m, argv);
}

抛出一个 MethodAndArgsCalle r异常,这个异常会被 ZygoteInit 的main 函数捕获,如下所示。 ZygoteInit

  public static void main(String argv[]) {
     ...
        try {
           ...
        } catch (MethodAndArgsCaller caller) {
            //执行caller的run
            caller.run();
        } catch (RuntimeException ex) {
            Log.e(TAG, "Zygote died with exception", ex);
            closeServerSocket();
            throw ex;
        }
    }

2.3.2 MethodAndArgsCaller

 public static class MethodAndArgsCaller extends Exception
            implements Runnable {
        private final Method mMethod;
        private final String[] mArgs;
        public MethodAndArgsCaller(Method method, String[] args) {
            mMethod = method;
            mArgs = args;
        }
        public void run() {
            try {
               //1.调用 ActivityThread#main
                mMethod.invoke(null, new Object[] { mArgs });
            } catch (IllegalAccessException ex) {
               ...
            }
            ...       
            }
        }
    }

mMethod 指的是 ActivityThread 的 main 函数,mArgs 指的是应用程序进程的启动参数。

2.3.3 ActivityThread#main

 public static void main(String[] args) {
        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");
        SamplingProfilerIntegration.start();
        ...
       //1.创建消息循环
        Looper.prepareMainLooper();//1
        //2.创建ActivityThread
        ActivityThread thread = new ActivityThread();
        thread.attach(false);
        if (sMainThreadHandler == null) {
            sMainThreadHandler = thread.getHandler();
        }
        ...
        //Looper的loop 消息循环
        Looper.loop();//3
        ...
    }