• 3.应用程序进程启动过程


    应用程序进程启动过程

    这篇文章只是对刘望舒大佬书籍的摘抄,适合复习用,没看过的请先看大佬的原书

    下面是大佬博客的链接
    Android进阶三部曲 第二部《Android进阶解密》

    一、应用程序进程启动过程介绍

    应用程序进程创建过程可以分为两个部分,分别是AMS发送启动应用进程请求以及Zygote接受请求并创建应用程序进程

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

    时序图如下

    请添加图片描述

    Ams如果想要启动应用就需要向Zygote进程发送创建应用进程的请求,AMS通过调用startProcessLocked方法向Zygote进程发送请求

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

    private final void startProcessLocked(ProcessRecord app, String hostingType,
          String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
      ...
      try {
          try {
              final int userId = UserHandle.getUserId(app.uid);
              AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
          } catch (RemoteException e) {
              throw e.rethrowAsRuntimeException();
          }
        	//获取要创建的应用程序进程的用户id
          int uid = app.uid;
          int[] gids = null;
          int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
          if (!app.isolated) {
              ...
              //对gids进行创建和赋值
              if (ArrayUtils.isEmpty(permGids)) {
                  gids = new int[3];
              } else {
                  gids = new int[permGids.length + 3];
                  System.arraycopy(permGids, 0, gids, 3, permGids.length);
              }
              gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
              gids[1] = UserHandle.getCacheAppGid(UserHandle.getAppId(uid));
              gids[2] = UserHandle.getUserGid(UserHandle.getUserId(uid));
          }
          ...
          //设置应用程序进程主线程的类名,如果是null则设置为"android.app.ActivityThread"
          if (entryPoint == null) entryPoint = "android.app.ActivityThread";
          Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
                  app.processName);
          checkTime(startTime, "startProcess: asking zygote to start proc");
          ProcessStartResult startResult;
          if (hostingType.equals("webview_service")) {
              startResult = startWebView(entryPoint,
                      app.processName, uid, uid, gids, debugFlags, mountExternal,
                      app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
                      app.info.dataDir, null, entryPointArgs);
          } else {
            //启动应用程序进程
              startResult = Process.start(entryPoint,
                      app.processName, uid, uid, gids, debugFlags, mountExternal,
                      app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
                      app.info.dataDir, invokeWith, entryPointArgs);
          }
          ...
      } catch (RuntimeException e) {
         ...
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51

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

    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 invokeWith,
                                String[] zygoteArgs) {
      return zygoteProcess.start(processClass, niceName, uid, gid, gids,
                  debugFlags, mountExternal, targetSdkVersion, seInfo,
                  abi, instructionSet, appDataDir, invokeWith, zygoteArgs);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    /frameworks/base/core/java/android/os/ZygoteProcess.java

    调用了ZygoteProcess的start方法

    public final Process.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 invokeWith,
                                                String[] zygoteArgs) {
      try {
          return startViaZygote(processClass, niceName, uid, gid, gids,
                  debugFlags, mountExternal, targetSdkVersion, seInfo,
                  abi, instructionSet, appDataDir, invokeWith, zygoteArgs);
      } catch (ZygoteStartFailedEx ex) {
          ...
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    private Process.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 invokeWith,
                                                      String[] extraArgs)
      throws ZygoteStartFailedEx {
      //创建字符串列表argsForZygote,并将应用进程的启动参数保存在argsForZygote中
      ArrayList<String> argsForZygote = new ArrayList<String>();
    
      // --runtime-args, --setuid=, --setgid=,
      // and --setgroups= must go first
      argsForZygote.add("--runtime-args");
      argsForZygote.add("--setuid=" + uid);
      argsForZygote.add("--setgid=" + gid);
      if ((debugFlags & Zygote.DEBUG_ENABLE_JNI_LOGGING) != 0) {
        argsForZygote.add("--enable-jni-logging");
      }
      ...
        synchronized(mLock) {
        //这里调用zygoteSendArgsAndGetResult方法发送请求到zygote进程中
        return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote);
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    private static Process.ProcessStartResult zygoteSendArgsAndGetResult(
          ZygoteState zygoteState, ArrayList<String> args)
          throws ZygoteStartFailedEx {
      try {
          // 检查参数是否有换行符
          int sz = args.size();
          for (int i = 0; i < sz; i++) {
              if (args.get(i).indexOf('\n') >= 0) {
                  throw new ZygoteStartFailedEx("embedded newlines not allowed");
              }
          }
        	//向zygote的inputStream写入参数
          final BufferedWriter writer = zygoteState.writer;
          final DataInputStream inputStream = zygoteState.inputStream;
          writer.write(Integer.toString(args.size()));
          writer.newLine();
          for (int i = 0; i < sz; i++) {
              String arg = args.get(i);
              writer.write(arg);
              writer.newLine();
          }
          writer.flush();
         
          Process.ProcessStartResult result = new Process.ProcessStartResult();
          //读取zygote的返回结果
          result.pid = inputStream.readInt();
          result.usingWrapper = inputStream.readBoolean();
    
          if (result.pid < 0) {
              throw new ZygoteStartFailedEx("fork() failed");
          }
          return result;
      } catch (IOException ex) {
          zygoteState.close();
          throw new ZygoteStartFailedEx(ex);
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    ,这里主要使用zygoteState对象获取zygote的socket通信流。写入创建进程的参数和读取返回的结果,而zygoteState对象来自于openZygoteSocketIfNeeded方法,它进行Socket连接成功并匹配ABI后会返回ZygoteState类型对象

    private ZygoteState openZygoteSocketIfNeeded(String abi) throws ZygoteStartFailedEx {
      Preconditions.checkState(Thread.holdsLock(mLock), "ZygoteProcess lock not held");
    
      if (primaryZygoteState == null || primaryZygoteState.isClosed()) {
        try {
          //与zygote建立Socket连接,mSocket为"zygote"
          primaryZygoteState = ZygoteState.connect(mSocket);
        } catch (IOException ioe) {
          throw new ZygoteStartFailedEx("Error connecting to primary zygote", ioe);
        }
      }
      //连接Zygote主模式返回的ZygoteState是否与启动应用进程所需要的ABI匹配
      if (primaryZygoteState.matches(abi)) {
        return primaryZygoteState;
      }
      // 如果不匹配,尝试连接Zygote辅模式,mSecondarySocket为"zygote_secondary"
      if (secondaryZygoteState == null || secondaryZygoteState.isClosed()) {
        try {
          secondaryZygoteState = ZygoteState.connect(mSecondarySocket);
        } catch (IOException ioe) {
          throw new ZygoteStartFailedEx("Error connecting to secondary zygote", ioe);
        }
      }
    	//连接Zygote辅模式返回的ZygoteState是否与启动应用进程所需要的ABI匹配
      if (secondaryZygoteState.matches(abi)) {
        return secondaryZygoteState;
      }
    
      throw new ZygoteStartFailedEx("Unsupported zygote ABI: " + abi);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    上一节中我们知道Zygote的main方法中会创建name为"zygote"的Server端Socket。openZygoteSocketIfNeeded方法里首页会和这个Socket连接并拿到连接的封装primaryZygoteState,然后判断primaryZygoteState是否与启动应用程序进程所需的ABI是否匹配,如果匹配就返回primaryZygoteState,否则就尝试连接Zygote的辅模式,名为zygote_secondary的Socket,同样也会判断是否匹配程序进程所需的ABI,如果也不匹配就抛出异常

    Zygote接受请求并创建应用程序进程

    时序图如下

    请添加图片描述

    从上面我们知道创建应用程序进程时会向zygote进程的Socket发送请求。而Zygote进程收到一个创建应用程序进程的请求,我们回到ZygoteInit的main方法

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

    public static void main(String argv[]) {
        ...
        //创建一个Server端的Socket,sockerName的值为"zygote"
        zygoteServer.registerServerSocket(socketName);
        ...
      	//等待AMS请求
        zygoteServer.runSelectLoop(abiList);
        zygoteServer.closeServerSocket();
      } catch (Zygote.MethodAndArgsCaller caller) {
        caller.run();
      } catch (Throwable ex) {
        ...
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

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

    void runSelectLoop(String abiList) throws Zygote.MethodAndArgsCaller {
        ArrayList<FileDescriptor> fds = new ArrayList<FileDescriptor>();
      	//ZygoteConnection的连接列表
        ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>();
      	//mServerSocket是registerServerSocket函数创建的服务端Socket
      	//这里获取该Socket的fd字段的值并添加到fd列表fds中。
        fds.add(mServerSocket.getFileDescriptor());//1
      	//让第0个为null
        peers.add(null);
      	//无限循环等待AMS的请求
        while (true) {
          	...
            for (int i = pollFds.length - 1; i >= 0; --i) {//3
                if ((pollFds[i].revents & POLLIN) == 0) {
                   //未就绪的fds跳过
                    continue;
                }
                if (i == 0) {
                  	//i == 0说明服务端Socket与客户端连接上了,也就是Zygote进程和Ams建立了连接
                  	//通过acceptCommandPeer得到ZygeteConnection对象。
                    ZygoteConnection newPeer = acceptCommandPeer(abiList);//4
                  	//添加到连接列表
                    peers.add(newPeer);
                  	//添加到fds中,while循环使用
                    fds.add(newPeer.getFileDesciptor());
                } else {
                  	//调用runOnce函数创建一个新的应用进程
                    boolean done = peers.get(i).runOnce(this);//5
                    ...
                }
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    这里主要调用ZygoteConnection的runOnce方法来进行处理请求数据

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

    boolean runOnce(ZygoteServer zygoteServer) throws Zygote.MethodAndArgsCaller {
    
      String args[];
      Arguments parsedArgs = null;
      FileDescriptor[] descriptors;
      try {
        //从Socket获取应用程序进程的启动参数
        args = readArgumentList();
        descriptors = mSocket.getAncillaryFileDescriptors();
      } catch (IOException ex) {
        Log.w(TAG, "IOException on command socket " + ex.getMessage());
        closeSocket();
        return true;
      }
      ...
       try {
        //将字符串数据封装成Arguments类型的对象
        parsedArgs = new Arguments(args);
       	...
    		//创建应用程序进程,forkAndSpecialize主要通过fork当前进程来创建一个子进程。forkAndSpecialize返回值pid为0表示运行在子进程,
        pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids,
                                       parsedArgs.debugFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo,
                                       parsedArgs.niceName, fdsToClose, fdsToIgnore, parsedArgs.instructionSet,
                                       parsedArgs.appDataDir);
      } catch (ErrnoException ex) {
       ...
      }
    
      try {
        if (pid == 0) {
          // 如果代码运行在子进程中
          zygoteServer.closeServerSocket();
          IoUtils.closeQuietly(serverPipeFd);
          serverPipeFd = null;
          //处理应用程序进程
          handleChildProc(parsedArgs, descriptors, childPipeFd, newStderr);
    
          // 永远不要到这里,子进程应该抛出 Zygote.MethodAndArgsCaller 或 exec()。
          return true;
        } else {
          // 在父进程... pid < 0 表示失败
          IoUtils.closeQuietly(childPipeFd);
          childPipeFd = null;
          return handleParentProc(pid, descriptors, serverPipeFd, parsedArgs);
        }
      } finally {
        IoUtils.closeQuietly(childPipeFd);
        IoUtils.closeQuietly(serverPipeFd);
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50

    这里通过forkAndSpecialize fork一个子进程后,调用handleChildProc处理新创建的进程

    private void handleChildProc(Arguments parsedArgs,
                                 FileDescriptor[] descriptors, FileDescriptor pipeFd, PrintStream newStderr)
      throws Zygote.MethodAndArgsCaller {
      ...
      if (parsedArgs.invokeWith != null) {
        WrapperInit.execApplication(parsedArgs.invokeWith,
                                    parsedArgs.niceName, parsedArgs.targetSdkVersion,
                                    VMRuntime.getCurrentInstructionSet(),
                                    pipeFd, parsedArgs.remainingArgs);
      } else {
        //调用zygoteInit方法
        ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion,
                              parsedArgs.remainingArgs, null /* classLoader */);
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

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

    public static final void zygoteInit(int targetSdkVersion, String[] argv,
          ClassLoader classLoader) throws Zygote.MethodAndArgsCaller {
      if (RuntimeInit.DEBUG) {
          Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from zygote");
      }
    
      Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit");
      RuntimeInit.redirectLogStreams();
    
      RuntimeInit.commonInit();
      //创建新应用进程的Binder线程池
      ZygoteInit.nativeZygoteInit();
      //初始化Application
      RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

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

    protected static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
      throws Zygote.MethodAndArgsCaller {
      ...
      final Arguments args;
      try {
        args = new Arguments(argv);
      } catch (IllegalArgumentException ex) {
        Slog.e(TAG, ex.getMessage());
        return;
      }
      //调用args.startClass静态的main方法 此处为"android.app.ActivityThread"类
      invokeStaticMain(args.startClass, args.startArgs, classLoader);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader)
      throws Zygote.MethodAndArgsCaller {
      Class<?> cl;
      try {
        //加载Class
        cl = Class.forName(className, true, classLoader);
      } catch (ClassNotFoundException ex) {
        ...
      }
      Method m;
      try {
        //找到类的main方法
        m = cl.getMethod("main", new Class[] { String[].class });
      } catch (NoSuchMethodException ex) {
        ...
      }
      ...
      //将方法和参数封装为MethodAndArgsCaller并作为异常抛出
      throw new Zygote.MethodAndArgsCaller(m, argv);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    invokeStaticMain抛出的MethodAndArgsCaller异常,会在ZygoteServer.java的main方法捕获。

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

    public static void main(String argv[]) {
      	...
      	//因为子进程是fork的所以也会有这么一套代码
        zygoteServer.runSelectLoop(abiList);
        zygoteServer.closeServerSocket();
      } catch (Zygote.MethodAndArgsCaller caller) {
      	//调用反射方法,即"android.app.ActivityThread"类的main方法
        caller.run();
      } catch (Throwable ex) {
        ...
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    最后通过反射调用的形式进入到了ActivityThread的main方法

    二、Binder线程池的启动过程

    Zygote接受请求并创建应用程序进程过程中会调用ZygoteInit.nativeZygoteInit方法启动Binder线程池

    我们来看下它

    private static final native void nativeZygoteInit();
    
    • 1

    nativeZygoteInit它是一个Native方法,定义在AndroidRuntime.cpp中

    /frameworks/base/core/jni/AndroidRuntime.cpp

    const JNINativeMethod methods[] = {
      { "nativeZygoteInit", "()V",
          (void*) com_android_internal_os_ZygoteInit_nativeZygoteInit },
    };
    
    • 1
    • 2
    • 3
    • 4

    这说明nativeZygoteInit对应的函数是com_android_internal_os_ZygoteInit_nativeZygoteInit

    static void com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env, jobject clazz)
    {
      gCurRuntime->onZygoteInit();
    }
    
    • 1
    • 2
    • 3
    • 4

    gCurRuntime是AndroidRuntime类型的指针,它是在AndroidRuntime初始化时创建的

    ...
    static AndroidRuntime* gCurRuntime = NULL;
    ...
    AndroidRuntime::AndroidRuntime(char* argBlockStart, const size_t argBlockLength) :
          mExitWithoutCleanup(false),
          mArgBlockStart(argBlockStart),
          mArgBlockLength(argBlockLength)
    {
      ...
      gCurRuntime = this;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    AppRuntime创建时就会调用AndroidRuntime的构造函数,gCurRuntime指针就会被初始化,它指向的是AppRuntime。我们查看AppRuntime的onZygoteInit,AppRuntime是在app_main.cpp文件里定义的

    /frameworks/base/cmds/app_process/app_main.cpp

    virtual void onZygoteInit()
    {
        sp<ProcessState> proc = ProcessState::self();
        ALOGV("App process: starting thread pool.\n");
      	//调用ProcessState的startThreadPool方法启动一个线程池,也就是Binder线程池
        proc->startThreadPool();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    /frameworks/native/libs/binder/ProcessState.cpp

    void ProcessState::startThreadPool()
    {
      AutoMutex _l(mLock);
      //mThreadPoolStarted标记Binder线程池是否启动过,
      if (!mThreadPoolStarted) {
        //设置mThreadPoolStarted为true,确保Binder线程池只会被启动一次。
        mThreadPoolStarted = true;
        spawnPooledThread(true);
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    void ProcessState::spawnPooledThread(bool isMain)
    {
      if (mThreadPoolStarted) {
        String8 name = makeBinderThreadName();
        ALOGV("Spawning new pooled thread, name=%s\n", name.string());
        //PoolThread即为一个Binder线程
        sp<Thread> t = new PoolThread(isMain);
        //调用PoolThread的run函数启动一个新的线程池
        t->run(name.string());
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    Binder线程是一个PoolThread,它也定义在ProcessState类中

    class PoolThread : public Thread
    {
    
    protected:
      virtual bool threadLoop()
      {
        //调用joinThreadPool函数将当前线程注册到Binder驱动程序中。这样这个线程就加入到了Binder线程池中
        IPCThreadState::self()->joinThreadPool(mIsMain);
        return false;
      }
    
      const bool mIsMain;
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    PoolThread类继承了Thread类,threadLoop方法会调用joinThreadPool方法,将当前线程注册到Binder驱动程序中。这样这个线程就加入到了Binder线程池中,新创建的应用进程就支持Binder进程间通信了。我们只需要创建当前进程的Binder对象,并将它注册到ServiceManager中就可以实现Binder进程间通信。而不必关心进程间如何通过Binder进行通信

  • 相关阅读:
    房产中介租房小程序系统开发搭建
    网站面临的主要漏洞和安全研究员发现问题
    Linux常用的调试工具
    PAT 1012 The Best Rank
    深入分析并可视化城市轨道数据
    python基础复习-基本语法元素
    数据结构上机1
    CentOS7 Docker Hugo + CDN 域名端口无法访问的问题
    android 自定义View:仿QQ拖拽效果
    国外大佬的 4 个项目 yyds
  • 原文地址:https://blog.csdn.net/qq_19269585/article/details/125453510