Android系統(tǒng)源碼分析--Process啟動(dòng)過程

由于四大組件的啟動(dòng)都涉及到進(jìn)程的啟動(dòng),因此我們這章先講一下進(jìn)程啟動(dòng)流程,然后再講四大組件的啟動(dòng)流程。

基礎(chǔ)知識(shí)

Android應(yīng)用程序框架層創(chuàng)建的應(yīng)用程序進(jìn)程具有兩個(gè)特點(diǎn),一是進(jìn)程的入口函數(shù)是ActivityThread.main,二是進(jìn)程天然支持Binder進(jìn)程間通信機(jī)制;這兩個(gè)特點(diǎn)都是在進(jìn)程的初始化過程中實(shí)現(xiàn)的。(引用自老羅安卓之旅-Android應(yīng)用程序進(jìn)程啟動(dòng)過程的源代碼分析

進(jìn)程按照重要性可以分為下面五類:

  • 前臺(tái)進(jìn)程(Foreground process)
  • 可見進(jìn)程(Visible process)
  • 服務(wù)進(jìn)程(Service process)
  • 后臺(tái)進(jìn)程(Background process)
  • 空進(jìn)程(Empty process)

進(jìn)程啟動(dòng)流程

AMS(ActivityMagagerService)啟動(dòng)進(jìn)程是從其成員函數(shù)startProcessLocked開始調(diào)用Process.start方法開始的。我們先看一下進(jìn)程啟動(dòng)的時(shí)序圖:

Process.jpg

1. 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 {
        // 請(qǐng)求Zygote進(jìn)程創(chuàng)建一個(gè)應(yīng)用進(jìn)程
        return startViaZygote(processClass, niceName, uid, gid, gids,
                debugFlags, mountExternal, targetSdkVersion, seInfo,
                abi, instructionSet, appDataDir, zygoteArgs);
     } catch (ZygoteStartFailedEx ex) {
        Log.e(LOG_TAG,
                "Starting VM process through Zygote failed");
        throw new RuntimeException(
                "Starting VM process through Zygote failed", ex);
     }
}

注意:傳入的第一個(gè)參數(shù)是“android.app.ActivityThread”,這是進(jìn)程初始化要加載的類,這個(gè)類加載到進(jìn)程之后,就會(huì)把這個(gè)類的靜態(tài)成員方法main作為進(jìn)程的入口。然后調(diào)用startViaZygote方法。

2. 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 {
        synchronized (Process.class) {
            ArrayList<String> argsForZygote = new ArrayList<String>();

            // 保存要?jiǎng)?chuàng)建應(yīng)用程序進(jìn)程的啟動(dòng)參數(shù)到argsForZygote中
            ...

            // 保存id到argsForZygote中
            ...

            // 保存其他信息到argsForZygote中
            ...

            // 請(qǐng)求Zygote進(jìn)程創(chuàng)建這個(gè)應(yīng)用進(jìn)程
            return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote);
        }
    }

這個(gè)方法主要是保存信息到argsForZygote中,然后調(diào)用openZygoteSocketIfNeeded,然后根據(jù)返回的值調(diào)用zygoteSendArgsAndGetResult方法,首先先看openZygoteSocketIfNeeded方法。

3. openZygoteSocketIfNeeded方法:

private static ZygoteState openZygoteSocketIfNeeded(String abi) throws ZygoteStartFailedEx {
        if (primaryZygoteState == null || primaryZygoteState.isClosed()) {
            try {
                // 通過調(diào)用ZygoteState.connect方法創(chuàng)建LocalSocket對(duì)象,以便將相應(yīng)參數(shù)傳入Zygote進(jìn)程
                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 {
                // 通過調(diào)用ZygoteState.connect方法創(chuàng)建LocalSocket對(duì)象,以便將相應(yīng)參數(shù)傳入Zygote進(jìn)程
                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);
    }

通過ZygoteState.connect放創(chuàng)建primaryZygoteState對(duì)象,如果第一次創(chuàng)建不成功,創(chuàng)建第二次。connect方法代碼如下:

4. ZygoteState.connect方法:

public static ZygoteState connect(String socketAddress) throws IOException {
            DataInputStream zygoteInputStream = null;
            BufferedWriter zygoteWriter = null;
            // 這個(gè)Socket由ZygoteInit.java文件中的ZygoteInit類在runSelectLoopMode函數(shù)偵聽的。
            final LocalSocket zygoteSocket = new LocalSocket();

            try {
                // 開始建立連接,在連接過程中,LocalSocket對(duì)象zygoteSocket會(huì)在/dev/socket目錄下找到
                // 一個(gè)對(duì)應(yīng)的zygote文件,然后將它與自己綁定起來,這就相當(dāng)于與Zygote進(jìn)程中的名稱為“zygote”
                // 的Socket建立了連接
                zygoteSocket.connect(new LocalSocketAddress(socketAddress,
                        LocalSocketAddress.Namespace.RESERVED));

                // 連接成功以后,首先獲取LocalSocket對(duì)象zygoteSocket的一個(gè)輸入流,并且保存在
                // zygoteInputStream中,以便獲得Zygote進(jìn)程發(fā)送過來的通信數(shù)據(jù)
                zygoteInputStream = new DataInputStream(zygoteSocket.getInputStream());

                // 又得到LocalSocket對(duì)象zygoteSocket的一個(gè)輸入流,并且保存在zygoteWriter中,以便
                // 可以向Zygote進(jìn)程發(fā)送通信數(shù)據(jù)
                zygoteWriter = new BufferedWriter(new OutputStreamWriter(
                        zygoteSocket.getOutputStream()), 256);
            } catch (IOException ex) {
                ...
            }

            String abiListString = getAbiList(zygoteWriter, zygoteInputStream);
            Log.i("Zygote", "Process: zygote socket opened, supported ABIS: " + abiListString);

            // 創(chuàng)建的LocalSocket對(duì)象zygoteSocket會(huì)保存在ZygoteState中
            return new ZygoteState(zygoteSocket, zygoteInputStream, zygoteWriter,
                    Arrays.asList(abiListString.split(",")));
        }

首先創(chuàng)建一個(gè)LocalSocket對(duì)象,這個(gè)LocalSocket對(duì)象是在ZygoteInit中的runSelectLoop函數(shù)進(jìn)行監(jiān)聽的。然后通過connect方法并且傳入連接地址連接該Socket,連接以后會(huì)獲取輸入流DataInputStream,以便獲得Zygote進(jìn)程發(fā)送過來的通信數(shù)據(jù),然后又獲取BufferedWriter輸入流,以便向Zygote進(jìn)程發(fā)送通信數(shù)據(jù)。最后會(huì)返回一個(gè)ZygoteState對(duì)象。下面我們看一下LocalSocket.connect方法。

5. LocalSocket.connect方法:

    public void connect(LocalSocketAddress endpoint) throws IOException {
        synchronized (this) {
            if (isConnected) {
                throw new IOException("already connected");
            }

            implCreateIfNeeded();
            impl.connect(endpoint, 0);
            isConnected = true;
            isBound = true;
        }
    }

如果已經(jīng)連接,拋出異常,因?yàn)檫B接完成后,會(huì)關(guān)閉連接,使用時(shí)在打開連接。最后調(diào)用native方法連接socket,并且改變連接標(biāo)簽。

6. 回到第二步,調(diào)用完openZygoteSocketIfNeeded返回參數(shù)ZygoteState傳入到zygoteSendArgsAndGetResult方法中:

    private static ProcessStartResult zygoteSendArgsAndGetResult(
            ZygoteState zygoteState, ArrayList<String> args)
            throws ZygoteStartFailedEx {
        try {
            // Throw early if any of the arguments are malformed. This means we can
            // avoid writing a partial response to the zygote.
            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");
                }
            }

            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();
            // Zygote進(jìn)程接收到這些數(shù)據(jù)之后,就會(huì)創(chuàng)建一個(gè)新的應(yīng)用程序進(jìn)程,并且將這個(gè)新創(chuàng)建的應(yīng)用程序進(jìn)程
            // 的PID返回給Activity管理服務(wù)AMS

            // Should there be a timeout on this?
            ProcessStartResult result = new ProcessStartResult();

            // Always read the entire result from the input stream to avoid leaving
            // bytes in the stream for future process starts to accidentally stumble
            // upon.
            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);
        }
    }

這方法通過Socket流的方式將啟動(dòng)進(jìn)程的信息發(fā)送出去,從步驟4可知,這個(gè)Socket的監(jiān)聽是ZygoteInit類中的runSelectLoop方法,我們接著看這個(gè)方法。

7. ZygoteInit.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 {
                    boolean done = peers.get(i).runOnce();
                    if (done) {
                        peers.remove(i);
                        fds.remove(i);
                    }
                }
            }
        }
    }

數(shù)據(jù)通過Socket發(fā)送以后,Zygote進(jìn)程接收到后會(huì)調(diào)用peers.get(i).runOnce()方法。這個(gè)peers.get(i)是獲取ZygoteConnection對(duì)象,表示一個(gè)Socket連接,然后調(diào)用它的runOnce方法。

8. ZygoteConnection.runOnce方法:

    boolean runOnce() throws ZygoteInit.MethodAndArgsCaller {

        String args[];
        Arguments parsedArgs = null;
        FileDescriptor[] descriptors;

        try {
            // 獲得創(chuàng)建應(yīng)用程序進(jìn)程需要的啟動(dòng)參數(shù),并且保存在一個(gè)Arguments對(duì)象parsedArgs中
            args = readArgumentList();
            descriptors = mSocket.getAncillaryFileDescriptors();
        } catch (IOException ex) {
            Log.w(TAG, "IOException on command socket " + ex.getMessage());
            closeSocket();
            return true;
        }

        ...

        /** the stderr of the most recent request, if avail */
        PrintStream newStderr = null;

        if (descriptors != null && descriptors.length >= 3) {
            newStderr = new PrintStream(
                    new FileOutputStream(descriptors[2]));
        }

        int pid = -1;
        FileDescriptor childPipeFd = null;
        FileDescriptor serverPipeFd = null;

        try {
            parsedArgs = new Arguments(args);

            if (parsedArgs.abiListQuery) {
                return handleAbiListQuery();
            }

            ...

            // 調(diào)用forkAndSpecialize方法來創(chuàng)建這個(gè)應(yīng)用程序進(jìn)程,最終通過函數(shù)fork在當(dāng)前進(jìn)程中創(chuàng)建一個(gè)子進(jìn)程,
            // 因此,當(dāng)它的返回值等于0時(shí),就表示是在新創(chuàng)建的子進(jìn)程中執(zhí)行的,這時(shí)候ZygoteConnection類就會(huì)調(diào)用
            // 成員函數(shù)handleChildProc來啟動(dòng)這個(gè)子進(jìn)程
            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) {
            ...
        } catch (IllegalArgumentException ex) {
            ...
        } catch (ZygoteSecurityException ex) {
            ...
        }

        try {
            if (pid == 0) {
                ...
                handleChildProc(parsedArgs, descriptors, childPipeFd, newStderr);

                return true;
            } else {
                ...
                return handleParentProc(pid, descriptors, serverPipeFd, parsedArgs);
            }
        } finally {
            ...
        }
    }

首先通過Zygote.forkAndSpecialize方法來創(chuàng)建一個(gè)新的進(jìn)程,并且返回其pid。因?yàn)槲覀冊(cè)诜中男陆ㄟM(jìn)程,因此我們只分析pid為0的情況,pid為0時(shí)會(huì)調(diào)用handleChildProc方法,

9. handleChildProc方法:

    private void handleChildProc(Arguments parsedArgs,
            FileDescriptor[] descriptors, FileDescriptor pipeFd, PrintStream newStderr)
            throws ZygoteInit.MethodAndArgsCaller {
        ...

        // End of the postFork event.
        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
        if (parsedArgs.invokeWith != null) {
            WrapperInit.execApplication(parsedArgs.invokeWith,
                    parsedArgs.niceName, parsedArgs.targetSdkVersion,
                    VMRuntime.getCurrentInstructionSet(),
                    pipeFd, parsedArgs.remainingArgs);
        } else {
            // 初始化運(yùn)行庫以及啟動(dòng)一個(gè)Binder線程池
            RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion,
                    parsedArgs.remainingArgs, null /* classLoader */);
        }
    }

由于我們之前加入?yún)?shù)是沒有parsedArgs.invokeWith這個(gè)參數(shù),因此這里是null,因此會(huì)走else里面的代碼,執(zhí)行RuntimeInit.zygoteInit方法。

10. 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();

        // 首先調(diào)用下面函數(shù)來設(shè)置新創(chuàng)建的應(yīng)用程序進(jìn)程的時(shí)區(qū)和鍵盤布局等通用信息
        commonInit();
        // 然后調(diào)用下面Native函數(shù)在新創(chuàng)建的應(yīng)用程序進(jìn)程中啟動(dòng)一個(gè)Binder線程池
        nativeZygoteInit();
        applicationInit(targetSdkVersion, argv, classLoader);
    }

首先調(diào)用nativeZygoteInit函數(shù),這是一個(gè)native函數(shù),函數(shù)的目的是在新創(chuàng)建的應(yīng)用程序進(jìn)程中啟動(dòng)一個(gè)Binder線程池然后進(jìn)行進(jìn)程間通信。然后調(diào)用applicationInit函數(shù)

11. applicationInit函數(shù):

    private static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
            throws ZygoteInit.MethodAndArgsCaller {
        ...

        // Remaining arguments are passed to the start class's static main
        // 我們知道AMS指定了新創(chuàng)建的應(yīng)用程序進(jìn)程的入口函數(shù)為ActivityThread類的靜態(tài)成員函數(shù)main。實(shí)際是
        // 通過下面方法進(jìn)入到ActivityThread類的靜態(tài)成員函數(shù)main中的
        invokeStaticMain(args.startClass, args.startArgs, classLoader);
    }

我們?cè)谇懊嬷v過args.startClass傳入進(jìn)來的是"android.app.ActivityThread",表示要執(zhí)行"android.app.ActivityThread"的main函數(shù)。

12. invokeStaticMain函數(shù):

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

        try {
            cl = Class.forName(className, true, classLoader);
        } catch (ClassNotFoundException ex) {
            ...
        }

        Method m;
        try {
            // 獲取它的靜態(tài)成員函數(shù)main,并且保存在Method對(duì)象m中
            m = cl.getMethod("main", new Class[] { String[].class });
        } catch (NoSuchMethodException ex) {
            ...
        } catch (SecurityException ex) {
            ...
        }

        ...

        /*
         * This throw gets caught in ZygoteInit.main(), which responds
         * by invoking the exception's run() method. This arrangement
         * clears up all the stack frames that were required in setting
         * up the process.
         * 將這個(gè)Method對(duì)象封裝在一個(gè)MethodAndArgsCaller對(duì)象中,并且將這個(gè)MethodAndArgsCaller對(duì)象作為
         * 一個(gè)異常對(duì)象拋出來給當(dāng)前應(yīng)用程序處理
         */
        throw new ZygoteInit.MethodAndArgsCaller(m, argv);
        /**
         * 引用自Android系統(tǒng)源代碼情景分析中的Android進(jìn)程啟動(dòng)分析一文
         * 新創(chuàng)建的應(yīng)用程序進(jìn)程復(fù)制了Zygote進(jìn)程的地址空間,因此,當(dāng)前新創(chuàng)建的應(yīng)用程序進(jìn)程的調(diào)用棧與Zygote
         * 進(jìn)程的調(diào)用堆棧是一致的。Zygote進(jìn)程最開始執(zhí)行的是應(yīng)用程序app_process的入口函數(shù)main,接著再調(diào)用
         * ZygoteInit類的靜態(tài)成員函數(shù)main,最后進(jìn)入到ZygoteInit類的靜態(tài)成員函數(shù)runSelectLoopMode來循環(huán)
         * 等待Activity管理服務(wù)AMS發(fā)送過來的創(chuàng)建新的應(yīng)用進(jìn)程的請(qǐng)求。當(dāng)Zygote進(jìn)程收到AMS發(fā)送過來的創(chuàng)建新的
         * 應(yīng)用程序進(jìn)程的請(qǐng)求之后,它就會(huì)創(chuàng)建一個(gè)新的應(yīng)用程序進(jìn)程,并且讓這個(gè)新創(chuàng)建的應(yīng)用程序進(jìn)程沿著
         * ZygoteInit類的靜態(tài)函數(shù)runSelectLoopModel一直執(zhí)行到RuntimeInit類的靜態(tài)成員函數(shù)
         * invokeStaticMain。因此,當(dāng)RuntimeInit類的靜態(tài)成員函數(shù)invokeStaticMain拋出一個(gè)類型為
         * MethodAndArgsCaller的常時(shí),系統(tǒng)就會(huì)沿著這個(gè)調(diào)用過程往后找到一個(gè)適合的代碼塊來捕獲它。
         * 由于ZygoteInit函數(shù)main捕獲了類型為MethodAndArgsCaller的異常,因此,接下來它就會(huì)被調(diào)用,以便
         * 可以處理這里拋出的一個(gè)MethodAndArgsCaller異常。因此,拋出這個(gè)異常后,會(huì)執(zhí)行ZygoteInit中main
         * 函數(shù)中的catch來捕獲異常。
         *
         */
    }

這個(gè)就是通過類加載器加載ActivityThread,然后調(diào)用起main方法。然后拋出異常,通過ZygoteInit中main函數(shù)中的catch來捕獲異常。

13. ZygoteInit.main函數(shù):

    public static void main(String argv[]) {
        ...
        } catch (MethodAndArgsCaller caller) {
            // 捕獲MethodAndArgsCaller異常以后會(huì)調(diào)用MethodAndArgsCaller的run函數(shù)
            // ActivityThread.main
            caller.run();
        } catch (Throwable ex) {
            ...
        }
    }

通過步驟12可知拋出的異常是MethodAndArgsCaller異常,因此會(huì)執(zhí)行caller.run方法。

14. MethodAndArgsCaller.run:

        /**
         * 注釋來自Android系統(tǒng)源代碼情景分析
         * 這里開始調(diào)用ActivityThread.main方法,為什么要繞這么遠(yuǎn)呢,前面提到,AMS請(qǐng)求Zygote進(jìn)程創(chuàng)建的應(yīng)用
         * 程序進(jìn)程的入口函數(shù)為ActivityThread的main函數(shù),但是由于新創(chuàng)建的應(yīng)用程序進(jìn)程一開始就需要再內(nèi)部初始
         * 化運(yùn)行時(shí)庫,以及啟動(dòng)Binder線程池,因此,ActivityThread的main函數(shù)被調(diào)用時(shí),新創(chuàng)建的應(yīng)用程序進(jìn)程
         * 實(shí)際上已經(jīng)執(zhí)行了相當(dāng)多的代碼,為了使得西創(chuàng)建的應(yīng)用程序的進(jìn)程覺得它的入口函數(shù)就是ActivityThread類
         * 的main函數(shù),系統(tǒng)就不能直接調(diào)用,而是拋出異?;氐絑ygoteInit的main函數(shù)中,然后間接調(diào)用它,這樣就
         * 可以巧妙的利用Java語言的異常處理來清理它前面調(diào)用的堆棧了
         */
        public void run() {
            try {
                // 調(diào)用ActivityThread.main
                mMethod.invoke(null, new Object[]{mArgs});
            } catch (IllegalAccessException ex) {
                throw new RuntimeException(ex);
            } catch (InvocationTargetException ex) {
                Throwable cause = ex.getCause();
                if (cause instanceof RuntimeException) {
                    throw (RuntimeException) cause;
                } else if (cause instanceof Error) {
                    throw (Error) cause;
                }
                throw new RuntimeException(ex);
            }
        }

通過mMethod.invoke方法調(diào)用ActivityThread的main方法。

15. ActivityThread.mian方法:

    /**
     * 啟動(dòng)新的進(jìn)程時(shí)調(diào)用Process的start方法會(huì)最終調(diào)用改函數(shù)
     * 啟動(dòng)新的進(jìn)程主要做了兩件事:
     * 1.在進(jìn)程中創(chuàng)建了一個(gè)ActivityThread對(duì)象,并調(diào)用了它的成員函數(shù)attach向AMS發(fā)送一個(gè)啟動(dòng)完成的通知
     * 2.調(diào)用Looper類的靜態(tài)成員函數(shù)prepareMainLooper創(chuàng)建一個(gè)消息循環(huán),并且在向AMS發(fā)送啟動(dòng)完成通知后,
     *   使得當(dāng)前進(jìn)程進(jìn)入到這個(gè)消息循環(huán)中
     *
     * @param args
     */
    public static void main(String[] args) {
        ...

        // 創(chuàng)建looper
        Looper.prepareMainLooper();

        ActivityThread thread = new ActivityThread();
        // 傳入false表示非系統(tǒng)進(jìn)程啟動(dòng)
        thread.attach(false);

        if (sMainThreadHandler == null) {
            // 獲取主線程的Handler
            sMainThreadHandler = thread.getHandler();
        }

        ...

        // 開始無限循環(huán)
        Looper.loop();

        throw new RuntimeException("Main thread loop unexpectedly exited");
    }

這里主要是創(chuàng)建該線程的looper,然后創(chuàng)建ActivityThread對(duì)象,然后進(jìn)入消息循環(huán)。然后我們就可以啟動(dòng)Activity或者Service了。

原文地址:http://www.codemx.cn/2017/09/13/AndroidOS005-Process/

注:本文原創(chuàng),轉(zhuǎn)載請(qǐng)注明出處,多謝。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容