android启动及一些类含义

澳门新葡亰手机版 10

最近在为自己Moto
G定制Rom,顺便重新读了一遍Android 7.0的相关源码,特此记录当做笔记.

澳门新葡亰手机版 1

在开始正文之前,首先要明白冷启动和热启动.所谓冷启动就是启动该应用时,后台没有该应用的进程,此时系统会创建一个进程分配给它(AMS通过Socket和Zygote通信,Zygote通过forkAndSpecialize()方法向Linux内核申请新进程),之后会创建和初始化Application,然后通过反射执行ActivityThread中的main方法.而热启动则是,当启动应用的时候,后台已经存在该应用的进程,比如按home键返回主界面再打开该应用,此时会从已有的进程中来启动应用,这种方式下,不会重新走Application这一步.

此图盗用

那今天我们主要分析的是应用冷启动的过程.在分析过程中,我发现从Android
2.3到Android
7.0的启动流程总体变化不大,所以,无论你目前是用何版本,下文多是通用的.另外,在本文中,我省略掉了有关Binder这一部分,以便大部分人都能顺利阅读.

  1. 系统启动时init进程会创建Zygote进程,Zygote进程负责后续Android应用程序框架层的其它进程的创建和启动工作
  2. Zygote进程会首先创建一个SystemServer进程,SystemServer进程负责启动系统的关键服务,如包管理服务PackageManagerService和应用程序组件管理服务ActivityManagerService
  3. 当我们需要启动一个Android应用程序时,ActivityManagerService会通过Socket进程间通信机制,通知Zygote进程为这个应用程序创建一个新的进程。

从Launcher点击开始

Launcher就是我们所说的桌面,它本质也是一个apk,当我们点击桌面上的图标时,会调用Activity的startActivity(),最终调用startActivityForResult():

public void startActivityForResult(Intent intent, int requestCode, @Nullable Bundle options) {
    if (mParent == null) {
        Instrumentation.ActivityResult ar =
            mInstrumentation.execStartActivity(
                this, mMainThread.getApplicationThread(), mToken, this,
                intent, requestCode, options);
        // 省略多行代码
    } else {
       // 省略多行代码
    }
}

startActivityForResult将创建过程委托给Instrumenttation的execStartActivity():

public ActivityResult execStartActivity(
        Context who, IBinder contextThread, IBinder token, Activity target,
        Intent intent, int requestCode, Bundle options) {
    //重点关注IApplicationThread
    IApplicationThread whoThread = (IApplicationThread) contextThread;
    Uri referrer = target != null ? target.onProvideReferrer() : null;
    if (referrer != null) {
        intent.putExtra(Intent.EXTRA_REFERRER, referrer);
    }
    if (mActivityMonitors != null) {
        synchronized (mSync) {
            final int N = mActivityMonitors.size();
            for (int i=0; i<N; i++) {
                final ActivityMonitor am = mActivityMonitors.get(i);
                if (am.match(who, null, intent)) {
                    am.mHits++;
                    if (am.isBlocking()) {
                        return requestCode >= 0 ? am.getResult() : null;
                    }
                    break;
                }
            }
        }
    }
    try {
        intent.migrateExtraStreamToClipData();
        intent.prepareToLeaveProcess();
        // 重点关注ActivityManagerNative
        int result = ActivityManagerNative.getDefault()
            .startActivity(whoThread, who.getBasePackageName(), intent,
                    intent.resolveTypeIfNeeded(who.getContentResolver()),
                    token, target != null ? target.mEmbeddedID : null,
                    requestCode, 0, null, options);
        checkStartActivityResult(result, intent);
    } catch (RemoteException e) {
        throw new RuntimeException("Failure from system", e);
    }
    return null;
}

在该方法签名中,我们看到第二个参数contextThread是IBinder类型,继续往下看,发现contextThread实则是IApplicationThread的实现类.简单来看IApplicationThread的定义:

public interface IApplicationThread extends IInterface {
    void schedulePauseActivity(IBinder token, boolean finished, boolean userLeaving,
            int configChanges, boolean dontReport) throws RemoteException;
    void scheduleStopActivity(IBinder token, boolean showWindow,
            int configChanges) throws RemoteException;
    void scheduleWindowVisibility(IBinder token, boolean showWindow) throws RemoteException;
    void scheduleSleeping(IBinder token, boolean sleeping) throws RemoteException;
    void scheduleResumeActivity(IBinder token, int procState, boolean isForward, Bundle resumeArgs)
            throws RemoteException;
    void scheduleSendResult(IBinder token, List<ResultInfo> results) throws RemoteException;
    void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
            ActivityInfo info, Configuration curConfig, Configuration overrideConfig,
            CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor,
            int procState, Bundle state, PersistableBundle persistentState,
            List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents,
            boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) throws RemoteException;
    void scheduleRelaunchActivity(IBinder token, List<ResultInfo> pendingResults,
            List<ReferrerIntent> pendingNewIntents, int configChanges, boolean notResumed,
            Configuration config, Configuration overrideConfig) throws RemoteException;
    void scheduleNewIntent(List<ReferrerIntent> intent, IBinder token) throws RemoteException;
    void scheduleDestroyActivity(IBinder token, boolean finished,
            int configChanges) throws RemoteException;
    void scheduleReceiver(Intent intent, ActivityInfo info, CompatibilityInfo compatInfo,
            int resultCode, String data, Bundle extras, boolean sync,
            int sendingUser, int processState) throws RemoteException;
    // 省略多个方法
    void scheduleBindService(IBinder token,
            Intent intent, boolean rebind, int processState) throws RemoteException;
    void scheduleUnbindService(IBinder token,
            Intent intent) throws RemoteException;
    //省略多个方法
    void scheduleStopService(IBinder token) throws RemoteException;
    //省略多个方法
    void bindApplication(String packageName, ApplicationInfo info, List<ProviderInfo> providers,
            ComponentName testName, ProfilerInfo profilerInfo, Bundle testArguments,
            IInstrumentationWatcher testWatcher, IUiAutomationConnection uiAutomationConnection,
            int debugMode, boolean openGlTrace, boolean restrictedBackupMode, boolean persistent,
            Configuration config, CompatibilityInfo compatInfo, Map<String, IBinder> services,
            Bundle coreSettings) throws RemoteException;
    void scheduleExit() throws RemoteException;
    // 省略多行代码
    void scheduleRegisteredReceiver(IIntentReceiver receiver, Intent intent,
            int resultCode, String data, Bundle extras, boolean ordered,
            boolean sticky, int sendingUser, int processState) throws RemoteException;
    void scheduleLowMemory() throws RemoteException;
    void scheduleActivityConfigurationChanged(IBinder token, Configuration overrideConfig)
            throws RemoteException;
  //省略多个方法
    void scheduleTrimMemory(int level) throws RemoteException;
  //省略多个方法

}

通过大体的阅读IApplicationThread中代码,我们隐约有些熟悉,比如schedulePauseActivity方法应该就是负责Activity中Pause()执行的,scheduleLaunchActivity()应该是负责Activity创建的,scheduleBindService()负责Service绑定的,到现在,我们心里应该会想到IApplicationThread的真正实现类ApplicationThread(位于ActivityThread.java中)就是负责Activity,Service等的创建或其他操作,先来简单的看起其类关系图:

澳门新葡亰手机版 2

我们继续看Instrumentation的execStartActivity()方法:

int result = ActivityManagerNative.getDefault()
                .startActivity(whoThread, who.getBasePackageName(), intent,
                        intent.resolveTypeIfNeeded(who.getContentResolver()),
                        token, target != null ? target.mEmbeddedID : null,
                        requestCode, 0, null, options);

此时启动Activity这一操作交给了ActivityManagerNative.getDefault()的startActivity()方法.ActivityManagerNative是一个抽象类,继承了Binder,同时它又实现了IActivityManager接口,其实现类是ActivityManagerService(AMS).

ActivityManagerNative.getDefault()方法返回IActivityManager类型对象,其实现类是ActivityManagerProxy,其构造函数接受一个IBinder类型,其实就是ActivityManagerService对象,此时你应该发现ActivityManagerNative,IActivityManager以及ActivityManagerProxy三者之间的联系如下:

澳门新葡亰手机版 3

通过上图,我们看到这三者就是一个典型的代理模式:ActivityManagerProxy就是ActivityManagerService的远程代理,那么此时ActivityManagerNative的作用也就很明显:返回AMS的远程代理对象,这样Launcher应用就能和AMS服务通信了.

我们用一张图来简单的描述上述整个流程:

澳门新葡亰手机版 4

澳门新葡亰手机版 5

进入ActivityManagerService

现在我们跳到AMS的startActivity()方法继续往下看:

@Override
public int startActivity(IBinder whoThread, String callingPackage,
        Intent intent, String resolvedType, Bundle options) {
    checkCaller();

    int callingUser = UserHandle.getCallingUserId();
    TaskRecord tr;
    IApplicationThread appThread;
    synchronized (ActivityManagerService.this) {
        tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
        if (tr == null) {
            throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
        }
        appThread = ApplicationThreadNative.asInterface(whoThread);
        if (appThread == null) {
            throw new IllegalArgumentException("Bad app thread " + appThread);
        }
    }
  //交给mStackSupervisor继续
    return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
            resolvedType, null, null, null, null, 0, 0, null, null,
            null, options, false, callingUser, null, tr);
}

首先我们注意到该方法的第一个参数是IBinder类型,其实质就是前边ApplicationThread的实例,也就是ActivityThread中的mAppThread对象.接下来交给ActivityStackSupervisor实例的startActivityMayWait()继续启动:

final int startActivityMayWait(IApplicationThread caller, int callingUid,
            String callingPackage, Intent intent, String resolvedType,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            IBinder resultTo, String resultWho, int requestCode, int startFlags,
            ProfilerInfo profilerInfo, WaitResult outResult, Configuration config,
            Bundle options, boolean ignoreTargetSecurity, int userId,
            IActivityContainer iContainer, TaskRecord inTask) {
        // Refuse possible leaked file descriptors
        if (intent != null && intent.hasFileDescriptors()) {
            throw new IllegalArgumentException("File descriptors passed in Intent");
        }
        boolean componentSpecified = intent.getComponent() != null;

        // Don't modify the client's object!
        intent = new Intent(intent);

        // Collect information about the target of the Intent.
        ActivityInfo aInfo =
                resolveActivity(intent, resolvedType, startFlags, profilerInfo, userId);

        ActivityContainer container = (ActivityContainer)iContainer;
        synchronized (mService) {
            //省略多行代码
            int res = startActivityLocked(caller, intent, resolvedType, aInfo,
                    voiceSession, voiceInteractor, resultTo, resultWho,
                    requestCode, callingPid, callingUid, callingPackage,
                    realCallingPid, realCallingUid, startFlags, options, ignoreTargetSecurity,
                    componentSpecified, null, container, inTask);
            // 省略多行代码

            return res;
        }
    }

该方法看起来非常复杂,但是流程确实蛮清晰的,通过resolveActivity()方法来获取ActivityInfo,接下来是一些其他操作(在不影响流程的前提下,省略多行),然后继续调用startActivityLocked():

final int startActivityLocked(IApplicationThread caller,
            Intent intent, String resolvedType, ActivityInfo aInfo,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            IBinder resultTo, String resultWho, int requestCode,
            int callingPid, int callingUid, String callingPackage,
            int realCallingPid, int realCallingUid, int startFlags, Bundle options,
            boolean ignoreTargetSecurity, boolean componentSpecified, ActivityRecord[] outActivity,
            ActivityContainer container, TaskRecord inTask) {
        int err = ActivityManager.START_SUCCESS;
        //省略多行代码
        err = startActivityUncheckedLocked(r, sourceRecord, voiceSession, voiceInteractor,
                startFlags, true, options, inTask);

        return err;
    }

在该方法中,又继续调用了startActivityUncheckedLocked()方法,抛开其中细节,我们发现该方法中又继续调用了ActivityStack的resumeTopActivityLocked()来继续启动流程:

 final boolean resumeTopActivityLocked(ActivityRecord prev, Bundle options) {
        if (mStackSupervisor.inResumeTopActivity) {
            // Don't even start recursing.
            return false;
        }

        boolean result = false;
        try {
            // Protect against recursion.
            mStackSupervisor.inResumeTopActivity = true;
            if (mService.mLockScreenShown == ActivityManagerService.LOCK_SCREEN_LEAVING) {
                mService.mLockScreenShown = ActivityManagerService.LOCK_SCREEN_HIDDEN;
                mService.updateSleepIfNeededLocked();
            }
            //继续启动
            result = resumeTopActivityInnerLocked(prev, options);
        } finally {
            mStackSupervisor.inResumeTopActivity = false;
        }
        return result;
    }

从上面的代码看出,resumeTopActivitiesLocked()方法继续调用了resumeTopActivityInnerLocked()方法,该方法内部又反过来调用了ActivityStackSupervisor的resumeTopActivitiesLocked()方法

private boolean resumeTopActivityInnerLocked(ActivityRecord prev, Bundle options) {
                //省略多行代码

                mStackSupervisor.startSpecificActivityLocked(next, true, false);
                if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
                return true;
            }

在上述代码中,由于应用是第一次启动,因此这里跳过了一些判断代码,最终又调用了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);
        //该应用的进程已经存在
        if (app != null && app.thread != null) {
            try {
                if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
                        || !"android".equals(r.info.packageName)) {

                    app.addPackage(r.info.packageName, r.info.applicationInfo.versionCode,
                            mService.mProcessStats);
                }
                realStartActivityLocked(r, app, andResume, checkConfig);
                return;
            } catch (RemoteException e) {
                Slog.w(TAG, "Exception when starting activity "
                        + r.intent.getComponent().flattenToShortString(), e);
            }
        }

        //该应用的进程尚未创建,调用AMS的startProcessLocked()
        mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
                "activity", r.intent.getComponent(), false, false, true);
    }

应用是第一次启动,此时系统尚未为其创建进程,因此调用AMS的startProcessLocked()方法,如果该应用已经存在,则调用realStartActivityLocked()澳门新葡亰手机版,.由于这里我们的应用第一次启动,所以从startProcessLocked()往下看:

final ProcessRecord startProcessLocked(String processName,
        ApplicationInfo info, boolean knownToBeDead, int intentFlags,
        String hostingType, ComponentName hostingName, boolean allowWhileBooting,
        boolean isolated, boolean keepIfLarge) {
    return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,hostingName, allowWhileBooting, isolated, 0 , keepIfLarge,null , null , null,null);
}

该方法直接调用了其对应的重载方法,并在该其中继续调用了重载方法:

  private final void startProcessLocked(ProcessRecord app, String hostingType,
        String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
    long startTime = SystemClock.elapsedRealtime();
        //省略多行代码
        boolean isActivityProcess = (entryPoint == null);

        //默认情况下,entryPoint为null,此时虚拟机启动后默认从ActivityThread的main()方法执行
        if (entryPoint == null) entryPoint = "android.app.ActivityThread";
        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
                app.processName);

        //要求Zygote进程为其创建进程
        checkTime(startTime, "startProcess: asking zygote to start proc");
        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);
        checkTime(startTime, "startProcess: returned from zygote!");
        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);

       //省略多行代码
    } catch (RuntimeException e) {
        //省略
    }
}

到现在我们同样用一张图来描述这过程:

澳门新葡亰手机版 6

微信图片_20171012164156.png

走进Zygote

这里通过Process的start()方法来请求Zygote进程为其生成新进程,在start()方法中又直接调用了startViaZygote():

//processClass是调用者传的android.app.ActivityThread
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>();

            // --runtime-args, --setuid=, --setgid=,
            // and --setgroups= must go first
            //--runtime-agrs决定了新建进程执行方式,
            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");
            }
            if ((debugFlags & Zygote.DEBUG_ENABLE_SAFEMODE) != 0) {
                argsForZygote.add("--enable-safemode");
            }
            if ((debugFlags & Zygote.DEBUG_ENABLE_DEBUGGER) != 0) {
                argsForZygote.add("--enable-debugger");
            }
            if ((debugFlags & Zygote.DEBUG_ENABLE_CHECKJNI) != 0) {
                argsForZygote.add("--enable-checkjni");
            }
            if ((debugFlags & Zygote.DEBUG_ENABLE_JIT) != 0) {
                argsForZygote.add("--enable-jit");
            }
            if ((debugFlags & Zygote.DEBUG_GENERATE_DEBUG_INFO) != 0) {
                argsForZygote.add("--generate-debug-info");
            }
            if ((debugFlags & Zygote.DEBUG_ENABLE_ASSERT) != 0) {
                argsForZygote.add("--enable-assert");
            }
            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);

            //TODO optionally enable debuger
            //argsForZygote.add("--enable-debugger");

            // --setgroups is a comma-separated list
            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());
            }

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

            argsForZygote.add(processClass);

            if (extraArgs != null) {
                for (String arg : extraArgs) {
                    argsForZygote.add(arg);
                }
            }

            return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote);
        }
    }

上面的方法非常简单,设置一堆参数后然后又调用了zygoteSendArgsAndGetResult()向Zygote发送创建进程请求,该方法内部就是和Zygote进行Socket通信.Zygote接受到该请求,并将该请求封装为ZygoteConnection对象,具体代码在ZygoteInit.java当中,来看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) {
              //接受来自AMS的请求
                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);
                }
            }
        }
    }
}

此时Zygote作为服务端不断监听来自AMS的请求,通过acceptCommandPeer()将请求封装为ZygoteConection对象,并将Socket文件标识存在fds中,请求放在peers中.而runOnce()则在下一次循环中处理请求,具体代码如下:

boolean runOnce() throws ZygoteInit.MethodAndArgsCaller {

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

    try {
        //读取请求中的参数
        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 {
        //将请求参数封装成Arguments对象
        parsedArgs = new Arguments(args);

        //省略多行代码
        //创建新进程或者说创建VM实例
        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) {//pid=0表示刚才fork出的子进程
            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);
    }
}

上面的代码比较简单主要是读取请求参数并将其封装为Arguments对象,Arguments包含一下参数:

--setuid=
--setgid=
--target-sdk-version=
--enable-debugger
--enable-safemode
--enable-checkjni
--enable-jit
--generate-debug-info
--enable-jni-logging
--enable-assert
--runtime-args
--seinfo=
--capabilities=
--rlimit=
--setgroups=
--invoke-with
--nice-name=
--mount-external-default
--mount-external-read
--mount-external-write
--query-abi-list
--instruction-set=
--app-data-dir=

并通过Zygote的forkAndSpecialize()来生成新进程,成功后pid的值为0,这里我们只关心创建成功的情况,接下来,在新的进程中关闭从Zygote继承来的Socket,然后通过handleChildProc()继续后续操作.

private void handleChildProc(Arguments parsedArgs,
        FileDescriptor[] descriptors, FileDescriptor pipeFd, PrintStream newStderr)
        throws ZygoteInit.MethodAndArgsCaller {
    //关闭AMS和Zygote之间的Socket连接   
    closeSocket();
    ZygoteInit.closeServerSocket();

    if (descriptors != null) {
        try {
            Os.dup2(descriptors[0], STDIN_FILENO);
            Os.dup2(descriptors[1], STDOUT_FILENO);
            Os.dup2(descriptors[2], STDERR_FILENO);

            for (FileDescriptor fd: descriptors) {
                IoUtils.closeQuietly(fd);
            }
            newStderr = System.err;
        } catch (ErrnoException ex) {
            Log.e(TAG, "Error reopening stdio", ex);
        }
    }

    if (parsedArgs.niceName != null) {
        Process.setArgV0(parsedArgs.niceName);
    }

    // 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 {
      //寻找相应目标类的main()方法并执行
        RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion,
                parsedArgs.remainingArgs, null /* classLoader */);
    }
}

这里根据invokeWith参数决定使用哪种执行方式,invokeWith不为空则通过WrapperInit执行,否则通过RuntimeInit方式执行.对于这两者不做过多的解释,参数—runtime-args决定了新进程都是以RuntimeInit方式启动,目前就记住SystemServer和apk都是通过RuntimeInit来的即可.

Android的五层架构从上到下依次是应用层,应用框架层,库层,运行时层以及Linux内核层。
而在Linux中,它的启动可以归为一下几个流程:
Boot Loader-》初始化内核-》。。。。。。
当初始化内核之后,就会启动一个相当重要的祖先进程,也就是init进程,在Linux中所有的进程都是由init进程直接或间接fork出来的。
而对于Android来说,前面的流程都是一样的,而当init进程创建之后,会fork出一个Zygote进程,这个进程是所有Java进程的父进程。我们知道,Linux是基于C的,而Android是基于Java的(当然底层也是C)。所以这里就会fork出一个Zygote
Java进程用来fork出其他的进程。

走进RuntimeInit

现在来看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();

    commonInit();
    nativeZygoteInit();
    applicationInit(targetSdkVersion, argv, classLoader);
}

commonInit()为VM设置默认了线程异常处理器,然后调用了本地方法nativeZygoteInit(),其具体实现在AndroidRuntime.cpp下,位于frameworks/base/core/jni/AndroidRuntime.cpp

static void com_android_internal_os_RuntimeInit_nativeZygoteInit(JNIEnv* env, jobject clazz)
{
    gCurRuntime->onZygoteInit();
}

在该方法中又调用了其子类AppRutime的onZygoteInit()方法,AppRuntime位于frameworks/base/cmds/app_process/app_main.cpp

virtual void onZygoteInit()
{
    sp<ProcessState> proc = ProcessState::self();
    ALOGV("App process: starting thread pool.n");
    proc->startThreadPool();
}

为了不影响后文,我们先回到RuntimeInit的applicationInit():

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

    nativeSetExitWithoutCleanup(true);
    //VM设置
    VMRuntime.getRuntime().setTargetHeapUtilization(0.75f);
    VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);

    final Arguments args;
    try {
        args = new Arguments(argv);
    } catch (IllegalArgumentException ex) {
        Slog.e(TAG, ex.getMessage());
        // let the process exit
        return;
    }
    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);

    //反射执行ActivityThread的main函数
    invokeStaticMain(args.startClass, args.startArgs, classLoader);
}

其中最关键的就是invokeStaticMain()方法:

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) {
            throw new RuntimeException(
                    "Missing class when invoking static main " + className,
                    ex);
        }

        Method m;
        try {
            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);
        }

        //该异常会在ZygoteInit.main()中被捕获,然后在异常处理中调用MethodAndArgsCaller的run()
        //方法,这样就清除了进程中所有的栈帧
        throw new ZygoteInit.MethodAndArgsCaller(m, argv);
    }

在上面的代码中,最终的执行是通过抛出MethodAndArgsCaller的方式,来看一下MethodAndArgsCaller类的定义:

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

MethodAndArgsCaller继承Exception类并实现Runnable接口.但不管如何,现在最终开始执行ActivityThread的入口函数main():

public static void main(String[] args) {
    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");
    SamplingProfilerIntegration.start();
    CloseGuard.setEnabled(false);

    Environment.initForCurrentUser();
    EventLogger.setReporter(new EventLoggingReporter());

    AndroidKeyStoreProvider.install();
    final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
    TrustedCertificateStore.setDefaultUserDirectory(configDir);

    Process.setArgV0("<pre-initialized>");

    Looper.prepareMainLooper();

    ActivityThread thread = new ActivityThread();
    thread.attach(false);

    if (sMainThreadHandler == null) {
        sMainThreadHandler = thread.getHandler();
    }

    if (false) {
        Looper.myLooper().setMessageLogging(new
                LogPrinter(Log.DEBUG, "ActivityThread"));
    }

    // End of event ActivityThreadMain.
    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
    Looper.loop();

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

当main()开始运行时,主线程正式开始运行,这也就是我们所说的UI线程.同样我们用一张简单的图来描述上述过程:

澳门新葡亰手机版 7

当Zygote被初始化的时候,会fork出System
Server进程,这个进程在整个的Android进程中是非常重要的一个,地位和Zygote等同,它是属于Application
Framework层的,Android中的所有服务,例如AMS, WindowsManager,
PackageManagerService等等都是由这个SystemServer
fork出来的。所以它的地位可见一斑。

总结

到现在,我们已经完全走完应用冷启动的流程,上面的过程看起来繁琐,但是结合时序图来看应该是比较清晰的.抛开细节不看,那么上述的整个流程可以用下图概括:

澳门新葡亰手机版 8

最后为了方便系统理解整个流程,附上一张相对完整的时序图:

澳门新葡亰手机版 9

而当System
Server进程开启的时候,就会初始化AMS,同时,会加载本地系统的服务库,创建系统上下文,创建ActivityThread及开启各种服务等等。而在这之后,就会开启系统的Launcher程序,完成系统界面的加载与显示。

当我们点击桌面的APP图标时,Launcher进程会采用Binder的方式向AMS发出startActivity请求
• AMS在接收到请求之后,就会通过Socket向Zygote进程发送创建进程的请求
• Zygote进程会fork出新的子进程(APP进程)

之后APP进程会再向AMS发起一次请求,AMS收到之后经过一系列的准备工作再回传请求。

APP进程收到AMS返回的请求后,会利用Handler向主线程发送LAUNCH_ACTIVITY消息

主线程在收到消息之后,就创建目标Activity,并回调onCreate()/onStart()/onResume()等方法,UI渲染结束后便可以看到App主界面

Android的主线程就是ActivityThread,主线程的入口方法是main方法,在main方法中系统会通过Looper.prepareMainLooper()来创建主线程的Looper以及MessageQueue,并通过Looper.loop来开启消息循环,所以这一步实际上是系统已经为我们做了,我们就不再需要自己来做。
ActivityThread通过AppplicationThread和AMS进行进程件通信,AMS以进程间通信的方式完成ActivityThread的请求后会回调ApplicationThread中的Binder方法,然后ApplicationThread会向Handler发送消息,Handler收到消息后会将ApplicationThread中的逻辑切换到主线程中去执行,这个过程就是主线程的消息循环模型。
• 上面总结到了APP开始运行,依次调用onCreate/onStart/onResume等方法。

澳门新葡亰手机版 10

微信图片_20170623113005.png

第一、 引起调用AMS的对象通常有Context 、
Instrumentation、ActivityThread等调用ActivityManagerNative.getDefault()得到AMS的远程的代理ActivityManagerProxy对象。
第二、当AMS接受到来自某个应用程序传来的消息后,在AMS内部处理完毕后,会通过Binder机制回调回该应用程序所在进程的ApplicationThread类,即ActivityThread.java类。
第三、当ActivityThread接受到AMS传递过来的消息后,进行内部处理。如果需要的话,会继续与AMS通信。
最后,当整个通信完成时,ActivityThread会选择合适的对象,例如Service、Activity、BroadcastReceiver等去做相应的处理。

1、View.java
功能有: 绘制图形、处理触摸、按键事件等;
2、ActivityManagerService.java简称为 AMS
功能有:管理所有应用程序的Activity 、内存管理等 。
3、WindowManagerService.java简称为WMS
功能有:为所有应用程序分配窗口,并管理这些窗口
AMS作为一种系统级服务管理所有Activity,由于AMS记录了所有Activity的信息,当然能够主动的调度这些Activity,甚至在内存不足时,主动杀死后台的Activity.

ActivityManagerService.java
说明:该类的父类ActivityManagerNative实现IActivityManager,是一个Binder类,
即可实现跨进程通信,因此可以接受从客户端,例如Instrumentation、Context等调用过来的信息。
ActivityManagerService提供了全局的代理对象供IPC调用.

ActivityManagerProxy.java
说明:该类是远程AMS的代理,实现IActivityManager接口,应用程序进程ContextImpl,Instrumentation、ActivityThread等直接通过ActivityManagerNative.getDefault().即ActivityManagerProxy

ActivityThread:
说明:
该类为应用程序(即APK包)所对应进程(一个进程里可能有多个应用程序)的主线程类,即我们通常所说的UI线程/主线程,它里面存在一个main()方法,这也是APP的真正入口,当APP启动时,就会启动ActivityThread中的main方法,它会初始化一些对象,然后开启消息循环队列(之后总结),之后就会Looper.loop死循环,如果有消息就执行,没有就等着,也就是事件驱动模型(edt)的原理
ApplicationThread:
说明:该类是一个Binder类,即可实现跨进程通信。继承ApplicationThreadNative继承Binder,并且实现IApplicationThread接口
主要用于接受从AMS传递过来的消息,继而做相应处理,是Activity整个框架中客户端和服务端AMS之间通信的接口,同时也是ActivityThread的内部类。这样就有效的把ActivityThread和AMS绑定在一起了

ApplicationThreadProxy:
实现IApplicationThread接口,是远程ApplicationThread
代理类,在AMS进程里面把ApplicationThread()
改造成ApplicationThreadProxy。