美文网首页Android开发经验谈Android技术知识Android开发
Android 四大组件 - 进程的 fork 创建过程

Android 四大组件 - 进程的 fork 创建过程

作者: 你也不知道 | 来源:发表于2020-05-11 12:37 被阅读0次

相关文章链接:

1. Android Framework - 学习启动篇

2. Android 系统服务 - AMS 的启动过程

3. Android 系统服务 - PMS 的启动过程

4. Android Framework - 开机启动 Zygote 进程

相关源码文件:


/frameworks/base/services/core/java/android/os/Process.java

/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

/frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java

/frameworks/base/core/java/com/android/internal/os/Zygote.java

/frameworks/base/core/jni/com_android_internal_os_Zygote.cpp

/frameworks/base/core/java/android/app/ActivityThread.java

/frameworks/base/core/java/android/app/LoadedApk.java

1. AMS 与 Zygote 通信过程

无论是点击桌面图标调用 startActivitySafely 还是直接调用 startActivity 在源码中都是调用的 startActivityForResult 方法。由于 Activity 的启动流程有些复杂,因此本文先从进程的 fork 创建过程来入手分析。


    void startSpecificActivityLocked(ActivityRecord r,

            boolean andResume, boolean checkConfig) {

        // Is this activity's process already running?

        ProcessRecord app = mService.getProcessRecordLocked(r.processName,

                r.info.applicationInfo.uid, true);

        r.task.stack.setLaunchTime(r);

        // 判断进程是否创建

        if (app != null && app.thread != null) {

          ...

        }

        // 当前进程没有创建则先创建进程

        mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,

                "activity", r.intent.getComponent(), false, false, true);

    }

    private final void startProcessLocked(ProcessRecord app, String hostingType,

            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {

        try {

            // 设置参数

            ...

            // 设置 entryPoint = "android.app.ActivityThread"

            boolean isActivityProcess = (entryPoint == null);

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



            synchronized (mPidsSelfLocked) {

                // 缓存 pid 和 进程信息

                this.mPidsSelfLocked.put(startResult.pid, app);

                ...

            }

            ...

        } catch (RuntimeException e) {

            ...

        }

    }

    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 {

        synchronized(Process.class) {

            ArrayList<String> argsForZygote = new ArrayList<String>();

            // 添加创建进程的基本参数

            argsForZygote.add("--runtime-args");

            argsForZygote.add("--setuid=" + uid);

            argsForZygote.add("--setgid=" + gid);

            ...

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

            ...

            // 向 zygote 发起创建进程的请求,通过 socket 的方式

            return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote);

        }

    }

    // 打开 zygot socket 连接

    private static ZygoteState openZygoteSocketIfNeeded(String abi) throws ZygoteStartFailedEx {

        if (primaryZygoteState == null || primaryZygoteState.isClosed()) {

            try {

                primaryZygoteState = ZygoteState.connect(ZYGOTE_SOCKET);

            } catch (IOException ioe) {

                throw new ZygoteStartFailedEx("Error connecting to primary zygote", ioe);

            }

        }

        if (primaryZygoteState.matches(abi)) {

            return primaryZygoteState;

        }

        // The primary zygote didn't match. Try the secondary.

        if (secondaryZygoteState == null || secondaryZygoteState.isClosed()) {

            try {

            secondaryZygoteState = ZygoteState.connect(SECONDARY_ZYGOTE_SOCKET);

            } catch (IOException ioe) {

                throw new ZygoteStartFailedEx("Error connecting to secondary zygote", ioe);

            }

        }

        if (secondaryZygoteState.matches(abi)) {

            return secondaryZygoteState;

        }

        throw new ZygoteStartFailedEx("Unsupported zygote ABI: " + abi);

    }

    private static ProcessStartResult zygoteSendArgsAndGetResult(

            ZygoteState zygoteState, ArrayList<String> args)

            throws ZygoteStartFailedEx {

        try {

            // 获取 socket 的 output 与 input

            final BufferedWriter writer = zygoteState.writer;

            final DataInputStream inputStream = zygoteState.inputStream;

            // 把数据传送给 zygote 进程

            writer.write(Integer.toString(args.size()));

            writer.newLine();

            int sz = args.size();

            for (int i = 0; i < sz; i++) {

                String arg = args.get(i);

                if (arg.indexOf('\n') >= 0) {

                    throw new ZygoteStartFailedEx(

                            "embedded newlines not allowed");

                }

                writer.write(arg);

                writer.newLine();

            }

            writer.flush();

            // 处理 zygote fork 进程返回的结果

            ProcessStartResult result = new ProcessStartResult();

            result.pid = inputStream.readInt();

            if (result.pid < 0) {

                throw new ZygoteStartFailedEx("fork() failed");

            }

            result.usingWrapper = inputStream.readBoolean();

            return result;

        } catch (IOException ex) {

            // 有异常则关闭连接

            zygoteState.close();

            throw new ZygoteStartFailedEx(ex);

        }

    }

activity 的启动过程中会掉用 startSpecificActivityLocked 方法,首先会根据 processName 和 uid 来判断进程是否有创建,如果没有创建进程则需要先创建进程,processName 默认情况是包名,uid 是由 PMS 在启动的过程中解析计算好的,其具体的计算赋值过程可以参考《Android 系统服务 - PMS 的启动过程》

如果当前进程没有创建,则调用 Process 的 startViaZygote 方法去创建进程,就是向 Zygote 进程发起创建进程的请求,这里跨进程通信采用的是 Socket 套接字的方式。注意,其中有一个重要的参数 entryPoint 是 android.app.ActivityThread 。

2. Zygote fork 创建进程


    // 循环读取处理请求

    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 {

                    boolean done = peers.get(i).runOnce();

                    if (done) {

                        peers.remove(i);

                        fds.remove(i);

                    }

                }

            }

        }

    }

    boolean runOnce() throws ZygoteInit.MethodAndArgsCaller {

        try {

            // 读取 AMS 发过来的参数

            args = readArgumentList();

        } catch (IOException ex) {

            ...

            return true;

        }



        try {

            parsedArgs = new Arguments(args);

            // fork 创建进程

            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) {

          ...

        }

        try {

            if (pid == 0) {

                // child process 处理

                handleChildProc(parsedArgs, descriptors, childPipeFd, newStderr);

                return true;

            } else {

                // parent process 处理

                return handleParentProc(pid, descriptors, serverPipeFd, parsedArgs);

            }

        } finally {

            IoUtils.closeQuietly(childPipeFd);

            IoUtils.closeQuietly(serverPipeFd);

        }

    }

    public static int forkAndSpecialize(int uid, int gid, int[] gids, int debugFlags,

          int[][] rlimits, int mountExternal, String seInfo, String niceName, int[] fdsToClose,

          String instructionSet, String appDataDir) {

        int pid = nativeForkAndSpecialize(

                  uid, gid, gids, debugFlags, rlimits, mountExternal, seInfo, niceName, fdsToClose,

                  instructionSet, appDataDir);

        ...

        return pid;

    }

    static pid_t ForkAndSpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArray javaGids,

                                    jint debug_flags, jobjectArray javaRlimits,

                                    jlong permittedCapabilities, jlong effectiveCapabilities,

                                    jint mount_external,

                                    jstring java_se_info, jstring java_se_name,

                                    bool is_system_server, jintArray fdsToClose,

                                    jstring instructionSet, jstring dataDir) {

      // 调用系统函数 fork

      pid_t pid = fork();

      ...

      return pid;

    }

    private void handleChildProc(Arguments parsedArgs,

            FileDescriptor[] descriptors, FileDescriptor pipeFd, PrintStream newStderr)

            throws ZygoteInit.MethodAndArgsCaller {

        // 关闭 zygote 进程继承过来的 socket 连接

        closeSocket();

        ZygoteInit.closeServerSocket();

        ...

        if (parsedArgs.invokeWith != null) {

            ...

        } else {

            RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion,

                    parsedArgs.remainingArgs, null /* classLoader */);

        }

    }

    public static final void zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)

            throws ZygoteInit.MethodAndArgsCaller {

        // common 初始化

        commonInit();

        // 初始化打开 binder 驱动

        nativeZygoteInit();

        // 抛异常,然后执行 ActivityThread.main 方法

        applicationInit(targetSdkVersion, argv, classLoader);

    }

Zygote 启动后会循环处理客户端发过来的请求,当接收到请求后会调用 ZygoteConnection 的 runOnce 方法,解析到客户端的参数后会调用 native 底层的 fork 的方法,至此进程才真正创建完毕。进程 fork 完毕后,Zygote 进程会将信息返回给 AMS,新创建的进程会调用 commonInit 、nativeZygoteInit 和 applicationInit 三个核心方法:

  • commonInit:通用初始化方法

  • nativeZygoteInit:打开底层 binder 驱动

  • applicationInit:调用 ActivityThread 的 main 方法

3. Application 的创建与绑定


    public static void main(String[] args) {

        // 创建主线程 Looper

        Looper.prepareMainLooper();

        ActivityThread thread = new ActivityThread();

        thread.attach(false);

        // 进入 loop 循环

        Looper.loop();

    }

    private void attach(boolean system) {

        if (!system) {

            final IActivityManager mgr = ActivityManagerNative.getDefault();

            try {

                // 像 AMS 发起绑定请求

                mgr.attachApplication(mAppThread);

            } catch (RemoteException ex) {

                // Ignore

            }

            ...

        } else {

          ...

        }

    }

    public final void attachApplication(IApplicationThread thread) {

        synchronized (this) {

            int callingPid = Binder.getCallingPid();

            final long origId = Binder.clearCallingIdentity();

            attachApplicationLocked(thread, callingPid);

            Binder.restoreCallingIdentity(origId);

        }

    }

    private final boolean attachApplicationLocked(IApplicationThread thread,

            int pid) {

        // 通过 pid 查询到进程信息,之前 fork 后有缓存

        ProcessRecord app;

        if (pid != MY_PID && pid >= 0) {

            synchronized (mPidsSelfLocked) {

                app = mPidsSelfLocked.get(pid);

            }

        } else {

            app = null;

        }

        ...

        // 绑定 thread

        app.makeActive(thread, mProcessStats);

        ...

        try {

            // 回调 bindApplication 方法

            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,

                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,

                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,

                    isRestrictedBackupMode || !normalMode, app.persistent,

                    new Configuration(mConfiguration), app.compat,

                    getCommonServicesLocked(app.isolated),

                    mCoreSettingsObserver.getCoreSettingsLocked());

        } catch (Exception e) {

            ...

            return false;

        }

        return true;

    }

    private void handleBindApplication(AppBindData data) {

        try {

            // 创建绑定 Application

            Application app = data.info.makeApplication(data.restrictedBackupMode, null);

            mInitialApplication = app;   

        } finally {

            StrictMode.setThreadPolicy(savedPolicy);

        }

    }

    public Application makeApplication(boolean forceDefaultAppClass,

            Instrumentation instrumentation) {

        if (mApplication != null) {

            return mApplication;

        }

        Application app = null;

        // 查找到 application 的 class

        String appClass = mApplicationInfo.className;

        if (forceDefaultAppClass || (appClass == null)) {

            // 默认是 android.app.Application

            appClass = "android.app.Application";

        }

        try {

            // 先创建 ClassLoader

            java.lang.ClassLoader cl = getClassLoader();

            if (!mPackageName.equals("android")) {

                initializeJavaContextClassLoader();

            }

            // 创建一个 ContextImpl

            ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);

            // 创建和绑定 Application

            app = mActivityThread.mInstrumentation.newApplication(

                    cl, appClass, appContext);

            appContext.setOuterContext(app);

        } catch (Exception e) {

            if (!mActivityThread.mInstrumentation.onException(app, e)) {

                throw new RuntimeException(

                    "Unable to instantiate application " + appClass

                    + ": " + e.toString(), e);

            }

        }

        mActivityThread.mAllApplications.add(app);

        mApplication = app;

        if (instrumentation != null) {

            try {

                // 调用 Application 的 onCreate 方法

                instrumentation.callApplicationOnCreate(app);

            } catch (Exception e) {

                if (!instrumentation.onException(app, e)) {

                    throw new RuntimeException(

                        "Unable to create application " + app.getClass().getName()

                        + ": " + e.toString(), e);

                }

            }

        }

        ...

        return app;

    }

    // 创建 application 并且调用 attach 方法

    static public Application newApplication(Class<?> clazz, Context context)

            throws InstantiationException, IllegalAccessException,

            ClassNotFoundException {

        Application app = (Application)clazz.newInstance();

        app.attach(context);

        return app;

    }

进程 fork 后会执行 ActivityThread 的 main 方法,该方法又会向 AMS 发起绑定 IApplicationThread 请求,这里 IApplicationThread 是一个可以跨进程通信的 Binder 对象,然后 AMS 又会调用 IApplicationThread 的 bindApplication 方法去创建应用的 Application,等应用的 Application 创建完毕后,才会真正的开始创建启动 Activity 。

视频地址:https://pan.baidu.com/s/1tB9hDc_6Aw_L0pgtbAU8Sw

视频密码:6fzw

相关文章

网友评论

    本文标题:Android 四大组件 - 进程的 fork 创建过程

    本文链接:https://www.haomeiwen.com/subject/vxcunhtx.html