App启动过程

现在网上有很多文章都在介绍如何启动一个Activity,但是基本上很少介绍当要启动的App进程不存在的时候,是怎么启动进程,又是如何启动Activity的,那这篇文章就是来看看如何启动进程启动Activity的,希望不要翻车,这里特别说明下面的代码是Android 7.0的源码,其它Android源码有些类或者方法找不到。

首先我们无论是在Launcher中启动或者在App内部启动一个Activity,都会执行到ActivityStackSupervisor.startSpecificActivityLocked()方法

void startSpecificActivityLocked(ActivityRecord r,
            boolean andResume, boolean checkConfig) {
    // Is this activity's application already running?
    ProcessRecord app = mService.getProcessRecordLocked(r.processName,
            r.info.applicationInfo.uid, true);
    r.task.stack.setLaunchTime(r);
    //  判断进程是否存在,存在就执行realStartActivityLocked方法
    if (app != null && app.thread != null) {
        //省略一些代码
        ...
        //  启动Activity
        realStartActivityLocked(r, app, andResume, checkConfig);
        return;
        //省略一些代码
        ....
    }
    
    //  进程不存在,调用ActivityManagerService的startProcessLocked方法启动新进程
    mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
            "activity", r.intent.getComponent(), false, false, true);
}

假如进程不存在,就会返回到ActivityManagerService启动新的进程

private final void startProcessLocked(ProcessRecord app, String hostingType,
            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
    //  省略一些代码
    .....

    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);
    //  省略一些代码
    .....
}

经过内部重载调用,走到这里,业务逻辑并不复杂,做一些调试标志位的设置什么的,就开始调用了Process的start方法。
Process的start方法会调用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) {
        //  省略一些代码
        .......
        return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote);
    }
}

这里也没有太多的业务逻辑,只是做了些配置,然后调用zygoteSendArgsAndGetResult方法,方法的第一个参数来自openZygoteSocketIfNeeded,返回一个socket;从这里我们就可以发现,其实这里是通过socket通信的
这里的socket是在Zygote进程启动,我们可以在ZygoteInit的main方法中看到

public static void main(String argv[]) {
        //省略代码
        .......
        registerZygoteSocket(socketName);
        //   这里已经写好注释了,用于接受socket连接命令
        Log.i(TAG, "Accepting command socket connections");
        runSelectLoop(abiList);
        
        //省略代码
                .......
}

在runSelectLoop方法中会调用ZygoteConnection的runOnce方法

boolean runOnce() throws ZygoteInit.MethodAndArgsCaller {
    //  省略部分代码
    .......
    try {
        if (pid == 0) {
            // in child
            IoUtils.closeQuietly(serverPipeFd);
            serverPipeFd = null;
            handleChildProc(parsedArgs, descriptors, childPipeFd, newStderr);

            // should never get here, the child is expected to either
            // throw ZygoteInit.MethodAndArgsCaller or exec().
            return true;
        } else {
            // in parent...pid of < 0 means failure
            IoUtils.closeQuietly(childPipeFd);
            childPipeFd = null;
            return handleParentProc(pid, descriptors, serverPipeFd, parsedArgs);
        }
    } finally {
        IoUtils.closeQuietly(childPipeFd);
        IoUtils.closeQuietly(serverPipeFd);
    }
}

开启应用时,这里的pid是0会调用handleChildProc方法,handleChildProc方法中RuntimeInit.zygoteInit方法,在此方法中又会调用applicationInit方法,有转到invokeStaticMain方法,其实这个方法最后会抛出一个异常

public static class MethodAndArgsCaller extends Exception
            implements Runnable {
    /** method to call */
    private final Method mMethod;

    /** argument array */
    private final String[] mArgs;

    public MethodAndArgsCaller(Method method, String[] args) {
        mMethod = method;
        mArgs = args;
    }

    public void run() {
        try {
            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);
        }
    }
}

抛出一样,一直到ZygoteInit的main才被catch掉,然后运行run方法,就导致应用的ActivityThread.main方法执行。

在ActivityThread.main方法里面创建完ActivityThread实例后,会调用attach方法。

private void attach(boolean system) {
    sCurrentActivityThread = this;
    mSystemThread = system;
    if (!system) {
        ViewRootImpl.addFirstDrawHandler(new Runnable() {
            @Override
            public void run() {
                ensureJitEnabled();
            }
        });
        android.ddm.DdmHandleAppName.setAppName("<pre-initialized>", UserHandle.myUserId());
        RuntimeInit.setApplicationObject(mAppThread.asBinder());
        final IActivityManager mgr = ActivityManagerNative.getDefault();
        try {
            mgr.attachApplication(mAppThread);
        } catch (RemoteException ex) {
            throw ex.rethrowFromSystemServer();
        }
    }
}

在这里,又回到了ActivityManagerService,attachApplication方法最终会调用attachApplicationLocked方法,在这里除去调用bindAppliaction,创建Application,还调用了ActivityStackSupervisor的attachApplicationLocked

boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {
    final String processName = app.processName;
    boolean didSomething = false;
    for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
        ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
        for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
            final ActivityStack stack = stacks.get(stackNdx);
            if (!isFocusedStack(stack)) {
                continue;
            }
            ActivityRecord hr = stack.topRunningActivityLocked();
            if (hr != null) {
                if (hr.app == null && app.uid == hr.info.applicationInfo.uid
                        && processName.equals(hr.processName)) {
                    try {
                        if (realStartActivityLocked(hr, app, true, true)) {
                            didSomething = true;
                        }
                    } catch (RemoteException e) {
                        Slog.w(TAG, "Exception in new application when starting activity "
                              + hr.intent.getComponent().flattenToShortString(), e);
                        throw e;
                    }
                }
            }
        }
    }
    if (!didSomething) {
        ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
    }
    return didSomething;
}

这个方法有再次调用了realStartActivityLocked用于启动Activity。

ActivityStackSupervisor->ActivityManagerService:startProcessLocked(.)
ActivityManagerService->ActivityManagerService:startProcessLocked(..)
ActivityManagerService->Process:start()
Process->Process:startViaZygote()
Process->Process:zygoteSendArgsAndGetResult()
Process->ZygoteInit:socket
ZygoteInit->ZygoteInit:runSelectLoop()
ZygoteInit->ZygoteConnection:runOnce()
ZygoteConnection->ZygoteConnection:handleChildProc()
ZygoteConnection->RuntimeInit:zygoteInit()
RuntimeInit->RuntimeInit:applicationInit()
RuntimeInit->RuntimeInit:invokeStaticMain()
RuntimeInit->ActivityThread:main()
ActivityThread->ActivityThread:attach()
ActivityThread->ActivityManagerService:attachApplication()
ActivityManagerService->ActivityManagerService:attachApplicationLocked()
ActivityManagerService->ActivityStackSupervisor:attachApplicationLocked()
ActivityStackSupervisor->ActivityManagerService:realStartActivityLocked()
    原文作者:fishpan
    原文地址: https://www.jianshu.com/p/0fb33ccdf166
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞