startActivity之进程启动

Android  源码分析  2023年12月5日 am8:08发布12个月前更新 城堡大人
137 0 0

前言

今天简单的记录一下App进程的启动过程。

继之前startActivity的分析(《startActivity源码分析1》和《startActivity源码分析2》)中的进程启动是一带而过的,聪明的你会发现,进程启动的大部分跟《Zygote的启动之二ZygoteInit》重合了。

正文

回到《startActivity源码分析1》文章末尾的startProcessLocked()。

ActivityManagerService.java

PS: 大部分内容都略了

startProcessLocked()
@GuardedBy("this")
final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
        boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
        boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
        String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
    //略
    final boolean success = startProcessLocked(app, hostingType, hostingNameStr, abiOverride);
    //略
}
startProcessLocked()
@GuardedBy("this")
private final boolean startProcessLocked(ProcessRecord app,
        String hostingType, String hostingNameStr, String abiOverride) {
    return startProcessLocked(app, hostingType, hostingNameStr,
            false /* disableHiddenApiChecks */, abiOverride);
}
startProcessLocked()
@GuardedBy("this")
private final boolean startProcessLocked(ProcessRecord app, String hostingType,
        String hostingNameStr, boolean disableHiddenApiChecks, String abiOverride) {
    //日志显示,前面几个startProcessLocked()会被调用2次
    //第一次app.pendingStart=false;第二次app.pendingStart=true;
    //因此第二次直接返回
    if (app.pendingStart) {
        return true;
    }
    //略
    try {
        try {
            final int userId = UserHandle.getUserId(app.uid);
            //PackageManagerService.java中检测
            //(1)判断是否存在(2)判断是否安装等,如果有问题就抛出异常
            AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
        } catch (RemoteException e) {
            throw e.rethrowAsRuntimeException();
        }
        //略
        //false
        if (!app.isolated) {
        }
        //略
        //注意,这里传入了android.app.ActivityThread
        final String entryPoint = "android.app.ActivityThread";
        //进入下一个startProcessLocked()
        return startProcessLocked(hostingType, hostingNameStr, entryPoint, app, uid, gids,
                runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet, invokeWith,
                startTime);
    } catch (RuntimeException e) {
        forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
                false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
        return false;
    }
}

这里有个重点,参数中传入了entryPoint,而entryPoint是

final String entryPoint = "android.app.ActivityThread";

fork出子进程后会启动android.app.ActivityThread

startProcessLocked()
@GuardedBy("this")
private boolean startProcessLocked(String hostingType, String hostingNameStr, String entryPoint,
        ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
        String seInfo, String requiredAbi, String instructionSet, String invokeWith,
        long startTime) {
    //略
    //异步启动 true
    if (mConstants.FLAG_PROCESS_START_ASYNC) {
        //使用Handler的post,也就是异步执行。
        //会先返回return
        mProcStartHandler.post(() -> {
            try {
                synchronized (ActivityManagerService.this) {
                    final String reason = isProcStartValidLocked(app, startSeq);
                    //reason为null
                    if (reason != null) {
                        app.pendingStart = false;
                        return;
                    }
                    app.usingWrapper = invokeWith != null
                            || SystemProperties.get("wrap." + app.processName) != null;
                    mPendingStarts.put(startSeq, app);
                }
                //启动进程startProcess,关键点
                final ProcessStartResult startResult = startProcess(app.hostingType, entryPoint,
                        app, app.startUid, gids, runtimeFlags, mountExternal, app.seInfo,
                        requiredAbi, instructionSet, invokeWith, app.startTime);
                synchronized (ActivityManagerService.this) {
                    handleProcessStartedLocked(app, startResult, startSeq);
                }
            } catch (RuntimeException e) {
                synchronized (ActivityManagerService.this) {
                    mPendingStarts.remove(startSeq);
                    app.pendingStart = false;
                    forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid),
                            false, false, true, false, false,
                            UserHandle.getUserId(app.userId), "start failure");
                }
            }
        });
        return true;
    } else {
        try {
            final ProcessStartResult startResult = startProcess(hostingType, entryPoint, app,
                    uid, gids, runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet,
                    invokeWith, startTime);
            handleProcessStartedLocked(app, startResult.pid, startResult.usingWrapper,
                    startSeq, false);
        } catch (RuntimeException e) {
            app.pendingStart = false;
            forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid),
                    false, false, true, false, false,
                    UserHandle.getUserId(app.userId), "start failure");
        }
        return app.pid > 0;
    }
}
startProcess()
private ProcessStartResult startProcess(String hostingType, String entryPoint,
        ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
        String seInfo, String requiredAbi, String instructionSet, String invokeWith,
        long startTime) {
    try {
        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
                app.processName);
        //hostingType这里是启动activity,
        if (hostingType.equals("webview_service")) {
            startResult = startWebView(entryPoint,
                    app.processName, uid, uid, gids, runtimeFlags, mountExternal,
                    app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
                    app.info.dataDir, null,
                    new String[] {PROC_START_SEQ_IDENT + app.startSeq});
        } else {
            //走这里,进入了Process
            startResult = Process.start(entryPoint,
                    app.processName, uid, uid, gids, runtimeFlags, mountExternal,
                    app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
                    app.info.dataDir, invokeWith,
                    new String[] {PROC_START_SEQ_IDENT + app.startSeq});
        }
        checkTime(startTime, "startProcess: returned from zygote!");
        return startResult;
    } finally {
        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
    }
}

Process.java

start()
public static final ProcessStartResult start(final String processClass,
                              final String niceName,
                              int uid, int gid, int[] gids,
                              int runtimeFlags, int mountExternal,
                              int targetSdkVersion,
                              String seInfo,
                              String abi,
                              String instructionSet,
                              String appDataDir,
                              String invokeWith,
                              String[] zygoteArgs) {
    return zygoteProcess.start(processClass, niceName, uid, gid, gids,
                runtimeFlags, mountExternal, targetSdkVersion, seInfo,
                abi, instructionSet, appDataDir, invokeWith, zygoteArgs);
}

ZygoteProcess.java

start()
public final Process.ProcessStartResult start(final String processClass,
                                              final String niceName,
                                              int uid, int gid, int[] gids,
                                              int runtimeFlags, int mountExternal,
                                              int targetSdkVersion,
                                              String seInfo,
                                              String abi,
                                              String instructionSet,
                                              String appDataDir,
                                              String invokeWith,
                                              String[] zygoteArgs) {
    try {
        return startViaZygote(processClass, niceName, uid, gid, gids,
                runtimeFlags, mountExternal, targetSdkVersion, seInfo,
                abi, instructionSet, appDataDir, invokeWith, false /* startChildZygote */,
                zygoteArgs);
    } catch (ZygoteStartFailedEx ex) {
        throw new RuntimeException(
                "Starting VM process through Zygote failed", ex);
    }
}
startViaZygote()
private Process.ProcessStartResult startViaZygote(final String processClass,
                                                  final String niceName,
                                                  final int uid, final int gid,
                                                  final int[] gids,
                                                  int runtimeFlags, int mountExternal,
                                                  int targetSdkVersion,
                                                  String seInfo,
                                                  String abi,
                                                  String instructionSet,
                                                  String appDataDir,
                                                  String invokeWith,
                                                  boolean startChildZygote,
                                                  String[] extraArgs)
                                                  throws ZygoteStartFailedEx {
    ArrayList<String> argsForZygote = new ArrayList<String>();
    //argsForZygote保存相关信息,进程uid,gid等等
    argsForZygote.add("--runtime-args");
    argsForZygote.add("--setuid=" + uid);
    argsForZygote.add("--setgid=" + gid);
    argsForZygote.add("--runtime-flags=" + runtimeFlags);
    if (mountExternal == Zygote.MOUNT_EXTERNAL_DEFAULT) {
        argsForZygote.add("--mount-external-default");
    } else if (mountExternal == Zygote.MOUNT_EXTERNAL_READ) {
        argsForZygote.add("--mount-external-read");
    } else if (mountExternal == Zygote.MOUNT_EXTERNAL_WRITE) {
        argsForZygote.add("--mount-external-write");
    }
    argsForZygote.add("--target-sdk-version=" + targetSdkVersion);
    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());
    }
    //niceName是应用包名
    if (niceName != null) {
        argsForZygote.add("--nice-name=" + niceName);
    }
    if (seInfo != null) {
        argsForZygote.add("--seinfo=" + seInfo);
    }
    if (instructionSet != null) {
        argsForZygote.add("--instruction-set=" + instructionSet);
    }
    if (appDataDir != null) {
        argsForZygote.add("--app-data-dir=" + appDataDir);
    }
    //invokeWith为null
    if (invokeWith != null) {
        argsForZygote.add("--invoke-with");
        argsForZygote.add(invokeWith);
    }
    //startChildZygote = false
    if (startChildZygote) {
        argsForZygote.add("--start-child-zygote");
    }
    argsForZygote.add(processClass);
    if (extraArgs != null) {
        for (String arg : extraArgs) {
            argsForZygote.add(arg);
        }
    }
    synchronized(mLock) {
        //abi是平台架构类型,比如arm64-v8a,x86等,我这里是arm64-v8a
        //[重]openZygoteSocketIfNeeded()
        //[重]zygoteSendArgsAndGetResult()进程跟Zygote数据传输和读取返回结果
        return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote);
    }
}
openZygoteSocketIfNeeded()
@GuardedBy("mLock")
private ZygoteState openZygoteSocketIfNeeded(String abi) throws ZygoteStartFailedEx {
    Preconditions.checkState(Thread.holdsLock(mLock), "ZygoteProcess lock not held");
    //primaryZygoteState不为null
    if (primaryZygoteState == null || primaryZygoteState.isClosed()) {
        try {
            //看过Zygote启动的知道,Zygote存在主辅模式
            //比如我设备是以Zygote64位主(secondary),Zygote32位辅(secondary)模式
            //连接socket,这个是Zygote中创建的,
            primaryZygoteState = ZygoteState.connect(mSocket);
        } catch (IOException ioe) {
            throw new ZygoteStartFailedEx("Error connecting to primary zygote", ioe);
        }
        maybeSetApiBlacklistExemptions(primaryZygoteState, false);
        maybeSetHiddenApiAccessLogSampleRate(primaryZygoteState);
    }
    //具体使用哪种模式,跟abi有关
    if (primaryZygoteState.matches(abi)) {
        return primaryZygoteState;
    }
    //下面类型,但如果上面符合,就不会执行下面了。
    if (secondaryZygoteState == null || secondaryZygoteState.isClosed()) {
        try {
            secondaryZygoteState = ZygoteState.connect(mSecondarySocket);
        } catch (IOException ioe) {
            throw new ZygoteStartFailedEx("Error connecting to secondary zygote", ioe);
        }
        maybeSetApiBlacklistExemptions(secondaryZygoteState, false);
        maybeSetHiddenApiAccessLogSampleRate(secondaryZygoteState);
    }
    if (secondaryZygoteState.matches(abi)) {
        return secondaryZygoteState;
    }
    throw new ZygoteStartFailedEx("Unsupported zygote ABI: " + abi);
}

回归一下之前介绍的,不同设备使用的配置不一样。

下面是几个zygote相关的rc文件。

  1. init.zygote32.rc

    Zygote 进程对应的执行程序是 app_process,也就是纯32位模式。

  2. init.zygote32_64.rc

    启动两个 Zygote 进程(zygote 和 zygote_secondary),对应的执行程序分别是 app_process32(主模式)和app_process64。

  3. init.zygote64.rc

    Zygote 进程对应的执行程序是app_process64,也就是纯64位模式

  4. init.zygote64_32.rc

    启动两个 Zygote 进程(zygote 和 zygote_secondary),对应的执行程序分别是 app_process64(主模式)和app_process32。

会根据primaryZygoteState和secondaryZygoteState的初始化,进程判断,如果都不满足(启动失败了或重启中),就抛出异常!

理论上,至少有一个满足条件。

因此,经过上面执行,已建成跟Zygote进行通信了,并返回ZygoteState。

zygoteSendArgsAndGetResult()
@GuardedBy("mLock")
private static Process.ProcessStartResult zygoteSendArgsAndGetResult(
        ZygoteState zygoteState, ArrayList<String> args)
        throws ZygoteStartFailedEx {
    try {
        //略
        //ZygoteState就是上面openZygoteSocketIfNeeded()获取的
        //获取writer和inputStream
        final BufferedWriter writer = zygoteState.writer;
        final DataInputStream inputStream = zygoteState.inputStream;
        //写启动上面组合的启动参数信息
        //此时就进入ZygoteServer.java中runSelectLoop()的死循环中啦
        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();
        //创建ProcessStartResult对象
        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);
    }
}

上面就是通过socket进程传输启动应用的新,因此,进入了ZygoteServer.java中runSelectLoop()中。

对于Zygote的socket的那块,推荐可以看参考文,之前我有跟过。

ZygoteServer.java

通过socket发送消息,runSelectLoop()会一直不断的循环并进行处理。

runSelectLoop()
Runnable runSelectLoop(String abiList) {
    //这部分第一次进入才执行,后面的进入了死循环了。
    //死循环
    while (true) {
        //略
        for (int i = pollFds.length - 1; i >= 0; --i) {
            //采用I/O多路复用机制,当客户端发出连接请求或者数据处理请求时,则执行continue
            if ((pollFds[i].revents & POLLIN) == 0) {
                continue;
            }
            if (i == 0) {
               //有socket客户端连接上
                ZygoteConnection newPeer = acceptCommandPeer(abiList);
                peers.add(newPeer);
                fds.add(newPeer.getFileDesciptor());
            } else {
                try {
                    //客户端发送了请求,获取connection
                    ZygoteConnection connection = peers.get(i);
                    //[重]处理发送来的消息,其实这里就处理fork出子进程
                    //切记,返回的是Runnable,这里进入
                    final Runnable command = connection.processOneCommand(this);
                  //这里要对fork有一定了解,创建子进程就是Zygote的分裂
                  //下面的if语句都会执行
                  //一个是走父进程流程关闭socket;一个是子进程流程,启动进程ActivityThread
                    if (mIsForkChild) {
                        //如果在子进程,command不为null
                        if (command == null) {
                            throw new IllegalStateException("command == null");
                        }
                        return command;
                    } else {
                        //父进程,command为null
                        if (command != null) {
                            throw new IllegalStateException("command != null");
                        }
                        //关闭socket等
                        if (connection.isClosedByPeer()) {
                            connection.closeSocket();
                            peers.remove(i);
                            fds.remove(i);
                        }
                    }
                } catch (Exception e) {
                    //略
                } finally {
                    mIsForkChild = false;
                }
            }
        }
    }
}

从socket中接收消息,然后进程fork出子进程(也就是从zygote中分裂而来)。

然后主进程流程关闭socket,子进程流程启动ActivityThread。

我们先挂住processOneCommand()这块。

ZygoteConnection.java

processOneCommand()
Runnable processOneCommand(ZygoteServer zygoteServer) {
    String args[];
    Arguments parsedArgs = null;
    FileDescriptor[] descriptors;
    try {
        //从socket读取命令
        args = readArgumentList();
        descriptors = mSocket.getAncillaryFileDescriptors();
    } catch (IOException ex) {
        throw new IllegalStateException("IOException on command socket", ex);
    }
    //如果没有参数,直接结束
    if (args == null) {
        isEof = true;
        return null;
    }
    int pid = -1;
    FileDescriptor childPipeFd = null;
    FileDescriptor serverPipeFd = null;
    //创建Arguments对象,这里会解析args中的命令
    parsedArgs = new Arguments(args);
    //根据参数值进行处理
    if (parsedArgs.abiListQuery) {
        handleAbiListQuery();
        return null;
    }
    //略
    //fork出子进程
    pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids,
            parsedArgs.runtimeFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo,
            parsedArgs.niceName, fdsToClose, fdsToIgnore, parsedArgs.startChildZygote,
            parsedArgs.instructionSet, parsedArgs.appDataDir);
    try {
        if (pid == 0) {
            //子进程流程
            zygoteServer.setForkChild();
            zygoteServer.closeServerSocket();
            IoUtils.closeQuietly(serverPipeFd);
            serverPipeFd = null;
            //[重]返回Runnable
            return handleChildProc(parsedArgs, descriptors, childPipeFd,
                    parsedArgs.startChildZygote);
        } else {
            IoUtils.closeQuietly(childPipeFd);
            childPipeFd = null;
            //如果是父进程流程
            handleParentProc(pid, descriptors, serverPipeFd);
            return null;
        }
    } finally {
        IoUtils.closeQuietly(childPipeFd);
        IoUtils.closeQuietly(serverPipeFd);
    }
}
handleChildProc()
private Runnable handleChildProc(Arguments parsedArgs, FileDescriptor[] descriptors,
        FileDescriptor pipeFd, boolean isZygote) {
    //关闭socket
    closeSocket();
    //根据之前传入参数,invokeWith=null
    if (parsedArgs.invokeWith != null) {
        WrapperInit.execApplication(parsedArgs.invokeWith,
                parsedArgs.niceName, parsedArgs.targetSdkVersion,
                VMRuntime.getCurrentInstructionSet(),
                pipeFd, parsedArgs.remainingArgs);
        throw new IllegalStateException("WrapperInit.execApplication unexpectedly returned");
    } else {
        //走这里
        //isZygote为false,是依赖parsedArgs.startChildZygote
        if (!isZygote) {
            return ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs,
                    null /* classLoader */);
        } else {
            return ZygoteInit.childZygoteInit(parsedArgs.targetSdkVersion,
                    parsedArgs.remainingArgs, null /* classLoader */);
        }
    }
}

ZygoteInit.java

zygoteInit()
public static final Runnable zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) {
    //这参数是ActivityManagerService.java中startProcessLocked()中[上面倒数第二个]传入的
    //argv中带有android.app.ActivityThread参数。
    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit");
    RuntimeInit.redirectLogStreams();
    RuntimeInit.commonInit();
    ZygoteInit.nativeZygoteInit();
    return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
}

RuntimeInit.java

applicationInit()
protected static Runnable applicationInit(int targetSdkVersion, String[] argv,
        ClassLoader classLoader) {
    nativeSetExitWithoutCleanup(true);
    VMRuntime.getRuntime().setTargetHeapUtilization(0.75f);
    VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);
    final Arguments args = new Arguments(argv);
    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
    //[重]看方法名就知道,找到main方法入口
    //args.startClass = android.app.ActivityThread
    return findStaticMain(args.startClass, args.startArgs, classLoader);
}
findStaticMain()
protected static Runnable findStaticMain(String className, String[] argv,
        ClassLoader classLoader) {
    Class<?> cl;
    //是不是很熟悉,反射
    try {
        cl = Class.forName(className, true, classLoader);
    } catch (ClassNotFoundException ex) {
        throw new RuntimeException(
                "Missing class when invoking static main " + className,
                ex);
    }
    Method m;
    try {
        //查找main函数入口
        m = cl.getMethod("main", new Class[] { String[].class });
    } catch (NoSuchMethodException ex) {
        throw new RuntimeException(
                "Missing static main on " + className, ex);
    } catch (SecurityException ex) {
        throw new RuntimeException(
                "Problem getting static main on " + className, ex);
    }
    int modifiers = m.getModifiers();
    if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {
        throw new RuntimeException(
                "Main method is not public and static on " + className);
    }
    //创建MethodAndArgsCaller,MethodAndArgsCaller实现于Runnable
    return new MethodAndArgsCaller(m, argv);
}
MethodAndArgsCaller
static class MethodAndArgsCaller implements Runnable {
    private final Method mMethod;
    private final String[] mArgs;
    public MethodAndArgsCaller(Method method, String[] args) {
        mMethod = method;
        mArgs = args;
    }
    public void run() {
        try {
            //Method = com.android.server.SystemServer的main函数
            //这里会启动ActivityThread并执行main()方法
            mMethod.invoke(null, new Object[] { mArgs });
        } catch (IllegalAccessException ex) {
            //略
        }
    }
}

到这里,Runnable已经创建了,但之前仅仅是创建了Runnable,但没有执行run(),因此我们要回到runSelectLoop()中。

ZygoteServer.java

再次回答runSelectLoop()中,里面有这段代码[只是部分]

try {
    //客户端发送了请求,获取connection
    ZygoteConnection connection = peers.get(i);
    //[重]处理发送来的消息,其实这里就处理fork出子进程
    //切记,返回的是Runnable,这里进入
    final Runnable command = connection.processOneCommand(this);
    //这里要对fork有一定了解,创建子进程就是Zygote的分裂
    //下面的if语句都会执行
    //一个是走父进程流程关闭socket;一个是子进程流程,启动进程ActivityThread
    if (mIsForkChild) {
        //如果在子进程,command不为null
        if (command == null) {
            throw new IllegalStateException("command == null");
        }
        return command;
    } else {
        //父进程,command为null
        if (command != null) {
            throw new IllegalStateException("command != null");
        }
        //关闭socket等
        if (connection.isClosedByPeer()) {
            connection.closeSocket();
            peers.remove(i);
            fds.remove(i);
        }
    }
} catch (Exception e) {
    //略
} finally {
    mIsForkChild = false;
}

上面也说了fork后,会有两个执行流程,一个是父进程流程,一个是子进程流程。我们关注子进程流程。

也就是mIsForkChild为true时,此时command不为null,而是

command = new MethodAndArgsCaller(m, argv);

也就是runSelectLoop()执行结束,并返回Runnable。

fork是把父类所有的资源都拷贝一份给子进程,因此,上面退出的runSelectLoop()循环是子类的。

子类用户父类Zygote一样的代码流程。ZygoteInit.java是进入Java世界的第一扇大门!

runSelectLoop()也是在ZygoteInit.java中main()方法中的。

ZygoteInit.java

public static void main(String argv[]) {
    //创建ZygoteServer
    ZygoteServer zygoteServer = new ZygoteServer();
    final Runnable caller;
    try {
        //略
        //[重]循环中。对于zygote不会退出,至于fork的子进程,是会退出的
        caller = zygoteServer.runSelectLoop(abiList);
    } catch (Throwable ex) {
        throw ex;
    } finally {
        //关闭socket
        zygoteServer.closeServerSocket();
    }
    //子进程退出的caller不为null
    if (caller != null) {
        caller.run();
    }
}

fork出的子进程才会退出runSelectLoop()循环,因此上面的call就是返回的Runnable对象,也就是这里main()方法结束后执行了

MethodAndArgsCaller.run();

然后进入了ActivityThread.java的main(),至于后面的,可以看《startActivity源码分析2》。

参考文章

  1. Zygote的启动之二ZygoteInit

  2. Zygote的启动之一app_main

  3. startActivity源码分析1

  4. startActivity源码分析2

  5. 《Android进阶解密-刘望舒》

 历史上的今天

  1. 2019: 郁达夫:北平的四季(0条评论)
  2. 2018: [转]Monkey测试基本命令(0条评论)
版权声明 1、 本站名称: 笔友城堡
2、 本站网址: https://www.biumall.com/
3、 本站部分文章来源于网络,仅供学习与参考,如有侵权,请留言

暂无评论

暂无评论...

随机推荐

ActionBar中Menu使用

前言简单记录一下标题栏中Menu的使用。流水文,之前没记录,这次有空重新简单记录一下。正文在Android Studio中新创建一个Module。在res目录创建menu,然后创建一个menu.xml/res/menu/menu.xmlmenu.xml<menu xmlns:a...

Android跳转WIFI界面的几种方式

前言简单记录一下Android跳转WiFi设置界面的启动方式。PS: 本文摘抄的,方便自己查阅。正文下面几种方式在Android P上测试OK。第一种try { Intent intent = new Intent(); intent.setAction("androi...

JNI之访问方法和域

前言JNI允许本地方法访问Java对象的域和调用方法。今天就介绍一下放问java方法和对象的域。记录一下,方便自己查阅。正文JNI访问对象域和方法,主要涉及如下几步骤:获取到对象域的jfieldID或jmethodID通过jfieldID获取对象域的值或者通过jmethodID...

赵雨:打算相爱是后来的事

你在你的街角走着不一定笑不一定相思 后来迎面就遇上了我低着头傻傻的在琢磨一首诗 你后来说他就像是一个落难的国王没有了土地也没有了宫殿却提着一大串钥匙 一个人能不能一下子美丽再一下子枯萎就像偷走了宫殿的强盗却没法子把门打开 ...

[摘]已知圆心,半径,角度,求圆上的任一点的坐标

前言原理很简单,大家初中都学过的,但,由于Java中的sin和cos传入的值是弧度,我一开始一直用角度,导致得不出对应的值。摘抄于此,方便自己查阅。好记性不如烂笔头正文PS:本文摘抄,只是文本继续一定编辑和整理。圆心坐标 :(x0, y0)半径 : r角度: a设圆上任何一点坐标...

[摘]Android面试题目整合

Java相关容器(HashMap、HashSet、LinkedList、ArrayList、数组等)内存模型垃圾回收算法(JVM)垃圾回收机制和调用System.gc()的区别?类加载过程(需要多看看,重在理解,对于热修复和插件化比较重要)反射多线程和线程池设计模式(六大基本原则、...