Android10.0应用进程创建过程以及Zygote的fork流程-[Android取经之路]

摘要:点击手机桌面图标,例如微信,它是如何启动的呢,让我们从系统源码级来一起分析。

阅读本文大约需要花费1小时。

文章的内容主要还是从源码进行分析,虽然又臭又长,但是如果想要学习Android系统源码,这是必要走的路,没有捷径。

相对于碎片学习,我更倾向于静下心来花费1个小时认真的学习一段内容。

文章首发微信公众号:大猫玩程序

专注于Android系统级源码分析,Android的平台设计,欢迎关注我,谢谢!

上一节我们讲完了Launcher的启动流程,这一节来看看应用进程的创建过程以及Zygote的fork流程。

系列文章:

 [1] Android系统架构

 [2]Android是怎么启动的

 [3]Android 10.0系统启动之init进程

 [4]Android10.0系统启动之Zygote进程

 [5]Android 10.0 系统启动之SystemServer进程

 [6]Android 10.0 系统服务之ActivityMnagerService

 [7]Android10.0系统启动之Launcher(桌面)启动流程

 [8]Android10.0应用进程创建过程以及Zygote的fork流程

1.概述

    上一节我们学习了Launcher的启动流程。这一节来介绍下应用进程的创建过程以及Zygote Fork的过程。

    点击桌面图标启动应用概述:

    在上一节Launcher的启动中我们知道了,手机的桌面其实就是Launcher进程,里面的应用图标都是Launcher通过ListView进行展示。

    那么我们点击一个桌面图标,比如微信,这个应用是如何启动的呢,这一节我们从系统级的源码来一步步的进行分析。

    在分析之前,我们简单区分一下进程和线程的概念。

    在Android中通过Logcat抓取log时,存在PID和TID两个概念。

    PID:Process ID,进程ID

    TID: Thread ID,线程ID

    每个Android都是一个进程,每个进程有一个或多个线程

进程:

    是并发执行的程序在执行过程中分配和管理资源的基本单位,是一个动态概念,竞争计算机系统资源的基本单位。

当我们点击某个应用的图标时,必须创建一个进程,该进程是由Zygote fork出来的,进程具有独立的资源空间,用于承载App上运行的各种Activity/Service等组件。


线程:

    是进程的一个执行单元,是进程内科调度实体。比进程更小的独立运行的基本单位。线程也被称为轻量级进程。

每个应用有多个线程,例如UI展示属于UI主线程,一些通信过程属于独立线程,通常JAVA中使用new Thread().start()来创建一个新的线程。

该线程并没有自己独立的地址空间,而是与其所在进程之间资源共享。

进程线程的区别

  1. 地址空间:同一进程的线程共享本进程的地址空间,而进程之间则是独立的地址空间。

  2. 资源拥有:同一进程内的线程共享本进程的资源,但是进程之间的资源是独立的。

  3. 一个进程崩溃后,在保护模式下不会对其他进程产生影响,但是一个线程崩溃整个进程都死掉。所以多进程要比多线程健壮。

  4. 进程切换时,消耗的资源大,效率高。所以涉及到频繁的切换时,使用线程要好于进程。同样如果要求同时进行并且又要共享某些变量的并发操作,只能用线程不能用进程。

  5. 执行过程:每个独立的进程有一个程序运行的入口、顺序执行序列和程序入口。但是线程不能独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。

  6. 线程是处理器调度的基本单位,但是进程不是。

  7. 两者均可并发执行。

2.核心源码

/libcore/dalvik/src/main/java/dalvik/system/ZygoteHooks.java
/libcore/libart/src/main/java/java/lang/Daemons.java
/libcore/dalvik/src/main/java/dalvik/system/runtime.cc
/art/runtime/native/dalvik_system_ZygoteHooks.cc
/art/runtime/runtime.cc
/frameworks/base/core/jni/com_android_internal_os_Zygote.cpp	

/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
/frameworks/base/core/java/com/android/internal/os/ZygoteServer.java
/frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java
/frameworks/base/core/java/com/android/internal/os/Zygote.java
/frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
/frameworks/base/services/java/com/android/server/SystemServer.java
/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
/frameworks/base/services/core/java/com/android/server/am/ProcessList.java
/frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
/frameworks/base/services/core/java/com/android/server/wm/ActivityStartController.java
/frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
/frameworks/base/services/core/java/com/android/server/wm/ActivityStack.java
/frameworks/base/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
/frameworks/base/services/core/java/com/android/server/wm/RootActivityContainer.java
/frameworks/base/services/core/java/com/android/server/wm/ClientLifecycleManager.java
/frameworks/base/core/java/android/os/Process.java
/frameworks/base/core/java/android/os/ZygoteProcess.java
/frameworks/base/core/java/android/app/LauncherActivity.java
/frameworks/base/core/java/android/app/ActivityThread.java
/frameworks/base/core/java/android/app/Activity.java
/frameworks/base/core/java/android/app/ActivityManagerInternal.java
/frameworks/base/core/java/android/app/servertransaction/ClientTransaction.java
/frameworks/base/core/java/android/app/servertransaction/ClientTransaction.aidl
/frameworks/base/core/java/android/app/ClientTransactionHandler.java
/frameworks/base/core/java/android/app/servertransaction/TransactionExecutor.java
/frameworks/base/core/java/android/app/servertransaction/LaunchActivityItem.java
/frameworks/base/core/java/android/app/Instrumentation.java
/frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java

3.架构

    App发起进程:点击一个桌面应用(例如微信),Launcher 加载应用, LauncherActivity收到触发事件,组装Intent,通过binder发送消息给SystemServer进程,调用Activity的startActivity()来启动进程,启动Activity时,受ActivityManagerService-AMS的服务控制,AMS属于SystemServer进程,因此SystemServer进行会通过Process 来向Zygote发送一个Socket。

    Zygote有一个无限循环,一直在等待Socket请求,收到SystemServer发来新的Socket请求后,Zygote调用系统的fork函数来孵化一个新的进程,比如这里的微信。

    再把启动的入口交给ActivityThread,进入微信的进程中,进行详细的UI展示。

3.1 进程创建图

    从点击Launcher中的图标,到启动Activity,再到Zygote Fork操作,最终进入新的进行进行UI绘制。

3.2 Zygote Fork图

    Zygote调用系统的fork()函数,孵化出一个新的进程,fork()采用copy-on-write机制,有些类如果不做改变,甚至都不用复制,子进程可以和父进程共享这部分数据,从而省去不少内存的占用。

 图片来源Gityuan

4.源码分析

    应用的启动共分以下四个步骤完成:

  1. 点击桌面的图标,Launcher调用系统的startActivity进行启动Activity,此时的动作在Launcher进程中

  2. ATM\AMS 进行Activity的处理,组装message,通过socket发送给Socket

  3. Zygote收到SystemServer发来的消息,进行消息拆分,再调用系统的fork()函数,进行进行孵化操作。

  4. 进入ActivityThread的main(),完成最终应用进程的的onCreate操作

    接下来我们根据这四个步骤来进行详细的源码分析.

4.1 第一阶段,点击桌面图标, 触发Launcher listview的点击事件 onListItemClick()

说明:桌面图标按照5*5或者6*6的方式进行排列,这其实是Launcher进程展示的ListView,每个应用图标填入其中,点击图标进入Launcher的点击事件处理

源码:

[LauncherActivity.java] onListItemClick()
protected void onListItemClick(ListView l, View v, int position, long id) {
	//ListView的点击事件也就是桌面的Icon的点击事件 ,这是整个启动流程的时间启动源。
    Intent intent = intentForPosition(position); //构造一个Intent
    startActivity(intent); //启动Activity,参考[4.1.1]
}

4.1.1 [Activity.java] startActivity()

说明:这里比较简单,调用startActivityForResult()

源码:

public void startActivity(Intent intent, @Nullable Bundle options) {
    if (options != null) {
		//调用startActivityForResult(),参考[4.1.2]
        startActivityForResult(intent, -1, options);
    } else {
        startActivityForResult(intent, -1);
    }
}

4.1.2 [Activity.java] startActivityForResult()

说明:不难发现,不论有没有父Activity,最终都交给了 Instrumentation 来开启

源码:

public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
        @Nullable Bundle options) {
	//  Activity mParent;  其实是一个Activity ,
	//判断是否有父类,没有父类的话交给Instrumentation
    if (mParent == null) {
        options = transferSpringboardActivityOptions(options);
        Instrumentation.ActivityResult ar =
            mInstrumentation.execStartActivity(
                this, mMainThread.getApplicationThread(), mToken, this,
                intent, requestCode, options);
        if (ar != null) {
			// 回调 ActivityResult
            mMainThread.sendActivityResult(
                mToken, mEmbeddedID, requestCode, ar.getResultCode(),
                ar.getResultData());
        }
        if (requestCode >= 0) {
            mStartedActivity = true;
        }

        cancelInputsAndStartExitTransition(options);
        // TODO Consider clearing/flushing other event sources and events for child windows.
    } else {
        if (options != null) {
			//最终调用的还是Instrumentation 的 execStartActivity(),参考[4.1.3]
            mParent.startActivityFromChild(this, intent, requestCode, options);
        } else {
            // Note we want to go through this method for compatibility with
            // existing applications that may have overridden it.
            mParent.startActivityFromChild(this, intent, requestCode);
        }
    }
}

4.1.3  [Instrumentation.java]  execStartActivity()

说明:Binder 调用 ActivityTaskManagerService-ATM 来启动 Activity

源码:

public ActivityResult execStartActivity(
        Context who, IBinder contextThread, IBinder token, Activity target,
        Intent intent, int requestCode, Bundle options) {
	...
    try {
        intent.migrateExtraStreamToClipData();
        intent.prepareToLeaveProcess(who);
        // Binder 调用 ATM 来启动 Activity, 参考[4.2.1]
        int result = ActivityTaskManager.getService()
            .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;
}

从下面代码可以看到,IActivityTaskManager其实获得的是activity_task对应服务的Binder对象,

即是ActivityTaskManagerService-ATM

[ActivityTaskManager.java]
public static IActivityTaskManager getService() {
    return IActivityTaskManagerSingleton.get();
}

private static final Singleton<IActivityTaskManager> IActivityTaskManagerSingleton =
    new Singleton<IActivityTaskManager>() {
        @Override
        protected IActivityTaskManager create() {
			//获取服务:ACTIVITY_TASK_SERVICE = "activity_task",对应的服务为ATM-ActivityTaskManagerService
            final IBinder b = ServiceManager.getService(Context.ACTIVITY_TASK_SERVICE);
            return IActivityTaskManager.Stub.asInterface(b);
        }
};

4.2 第二阶段:ATM\AMS 进行Activity的处理

调用栈如下:

4.2.1 [ActivityTaskManagerService.java]  startActivity()

说明:这里很简单,直接调用startActivityAsUser()

源码:

public final int startActivity(IApplicationThread caller, ...) {
	//参考[4.2.2]
    return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
            resultWho, requestCode, startFlags, profilerInfo, bOptions,
            UserHandle.getCallingUserId());
}

4.2.2 [ActivityTaskManagerService.java]  startActivityAsUser()

说明:获取 ActivityStarter 对象,最终调用ActivityStarter的execute()

源码:

int startActivityAsUser(IApplicationThread caller, String callingPackage,Intent intent, ...) {
	...
    // 获取 ActivityStarter 对象,最终调用ActivityStarter的execute(), 参考[4.2.3]
    return getActivityStartController().obtainStarter(intent, "startActivityAsUser")
            .setCaller(caller)
            .setCallingPackage(callingPackage)
            .setResolvedType(resolvedType)
            .setResultTo(resultTo)
            .setResultWho(resultWho)
            .setRequestCode(requestCode)
            .setStartFlags(startFlags)
            .setProfilerInfo(profilerInfo)
            .setActivityOptions(bOptions)
            .setMayWait(userId)  //这里调用了setMayWait(),因此ActivityStarter中的mRequest.mayWait为true
            .execute();
}

4.2.3 [ActivityStarter.java] execute()

说明:根据[4.2.2]中调用了setMayWait,因此这里的mRequest.mayWait为true

源码:

int execute() {
    try {
        // setMayWait()  方法中将设置mayWait的值为true
        //HomeActivity不设置,值为0
        if (mRequest.mayWait) { 
			//应用进程走这一步,参考[4.2.4]
            return startActivityMayWait(mRequest.caller, mRequest.callingUid,
                    mRequest.callingPackage, mRequest.realCallingPid, mRequest.realCallingUid,
                    mRequest.intent, mRequest.resolvedType,
                    mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
                    mRequest.resultWho, mRequest.requestCode, mRequest.startFlags,
                    mRequest.profilerInfo, mRequest.waitResult, mRequest.globalConfig,
                    mRequest.activityOptions, mRequest.ignoreTargetSecurity, mRequest.userId,
                    mRequest.inTask, mRequest.reason,
                    mRequest.allowPendingRemoteAnimationRegistryLookup,
                    mRequest.originatingPendingIntent, mRequest.allowBackgroundActivityStart);
        } else {
            //Home Activity走这一步
            return startActivity(mRequest.caller, mRequest.intent, mRequest.ephemeralIntent,
                    mRequest.resolvedType, mRequest.activityInfo, mRequest.resolveInfo,
                    mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
                    mRequest.resultWho, mRequest.requestCode, mRequest.callingPid,
                    mRequest.callingUid, mRequest.callingPackage, mRequest.realCallingPid,
                    mRequest.realCallingUid, mRequest.startFlags, mRequest.activityOptions,
                    mRequest.ignoreTargetSecurity, mRequest.componentSpecified,
                    mRequest.outActivity, mRequest.inTask, mRequest.reason,
                    mRequest.allowPendingRemoteAnimationRegistryLookup,
                    mRequest.originatingPendingIntent, mRequest.allowBackgroundActivityStart);
        }
    } finally {
        onExecutionComplete();
    }
}

4.2.4 [ActivityStarter.java] startActivityMayWait()

说明:调用startActivity()来启动Activity

源码:

private int startActivityMayWait(IApplicationThread caller, ... WaitResult outResult,
        ...) {
        ...
        final ActivityRecord[] outRecord = new ActivityRecord[1];
        //调用startActivity()来启动Activity,参考[4.2.5]
        int res = startActivity(caller, intent, ephemeralIntent, resolvedType, aInfo, rInfo,
                voiceSession, voiceInteractor, resultTo, resultWho, requestCode, callingPid,
                callingUid, callingPackage, realCallingPid, realCallingUid, startFlags, options,
                ignoreTargetSecurity, componentSpecified, outRecord, inTask, reason,
                allowPendingRemoteAnimationRegistryLookup, originatingPendingIntent,
                allowBackgroundActivityStart);
        ...
        //通知ActivityMetricsLogger,activity已经被启动起来
        //ActivityMetricsLogger 将等待windows被绘制出来
        mSupervisor.getActivityMetricsLogger().notifyActivityLaunched(res, outRecord[0]);
        if (outResult != null) {
           // 设置启动结果
            outResult.result = res;
            final ActivityRecord r = outRecord[0];
            switch(res) {
                case START_SUCCESS: {
                    mSupervisor.mWaitingActivityLaunched.add(outResult);
                    do {
                        try {
                            // 启动成功,等待启动结果
                            mService.mGlobalLock.wait();
                        } catch (InterruptedException e) {
                        }
                    } while (outResult.result != START_TASK_TO_FRONT
                            && !outResult.timeout && outResult.who == null);
                    if (outResult.result == START_TASK_TO_FRONT) {
                        res = START_TASK_TO_FRONT;
                    }
                    break;
                }
                ...
            }
        }
        return res;
    }
}

4.2.5 [ActivityStarter.java]   startActivity()

说明:延时布局,然后通过startActivityUnchecked()来处理启动标记 flag ,要启动的任务栈等,最后恢复布局

源码:

private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
            ActivityRecord[] outActivity, boolean restrictedBgActivity) {
    ...
    try {
        //延时布局
        mService.mWindowManager.deferSurfaceLayout();
        //调用 startActivityUnchecked ,一路调用到 resumeFocusedStacksTopActivities(),参考[4.2.6]
        result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
                startFlags, doResume, options, inTask, outActivity, restrictedBgActivity);
    } finally {
        //恢复布局
        mService.mWindowManager.continueSurfaceLayout();
    }
    ...
}

4.2.6 [RootActivityContainer.java] resumeFocusedStacksTopActivities()

 说明:获取栈顶的Activity,恢复它

 源码:

boolean resumeFocusedStacksTopActivities(
        ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
    ...
    //如果目标栈就是栈顶Activity,启动 resumeTopActivityUncheckedLocked()
    if (targetStack != null && (targetStack.isTopStackOnDisplay()
        || getTopDisplayFocusedStack() == targetStack)) {
    result = targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
    ...
    if (!resumedOnDisplay) {
        // 获取  栈顶的 ActivityRecord
        final ActivityStack focusedStack = display.getFocusedStack();
        if (focusedStack != null) {
            //最终调用 startSpecificActivityLocked(),参考[4.2.7]
            focusedStack.resumeTopActivityUncheckedLocked(target, targetOptions);
        }
    }
  }
}

4.2.7 [ActivityStackSupervisor.java] startSpecificActivityLocked()

说明:发布消息以启动进程,以避免在ATM锁保持的情况下调用AMS时可能出现死锁,最终调用到ATM的startProcess()

源码:

void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) {
        ...
        //发布消息以启动进程,以避免在ATM锁保持的情况下调用AMS时可能出现死锁
        //最终调用到AMS的startProcess(),参考[4.2.8]
        final Message msg = PooledLambda.obtainMessage(
                ActivityManagerInternal::startProcess, mService.mAmInternal, r.processName,
                r.info.applicationInfo, knownToBeDead, "activity", r.intent.getComponent());
        mService.mH.sendMessage(msg);
        ...
    }

4.2.8 [ActivityManagerService.java] startProcess()

说明:一路调用Process start(),最终到ZygoteProcess的attemptUsapSendArgsAndGetResult(),用来fork一个新的Launcher的进程

源码:

public void startProcess(String processName, ApplicationInfo info,
        boolean knownToBeDead, String hostingType, ComponentName hostingName) {
        ..
        //同步操作,避免死锁
        synchronized (ActivityManagerService.this) {
            //调用startProcessLocked,然后到 Process的start,最终到ZygoteProcess的attemptUsapSendArgsAndGetResult()
            //用来fork一个新的Launcher的进程,参考[4.2.9]
            startProcessLocked(processName, info, knownToBeDead, 0 /* intentFlags */,
                    new HostingRecord(hostingType, hostingName),
                    false /* allowWhileBooting */, false /* isolated */,
                    true /* keepIfLarge */);
        }
        ...
}

调用栈如下:

4.2.9 [ZygoteProcess.java]  attemptZygoteSendArgsAndGetResult()

说明:通过Socket连接Zygote进程,把之前组装的msg发给Zygote,其中processClass ="android.app.ActivityThread",通过Zygote进程来Fork出一个新的进程,并执行 "android.app.ActivityThread"的main方法

源码:

private Process.ProcessStartResult attemptZygoteSendArgsAndGetResult(
        ZygoteState zygoteState, String msgStr) throws ZygoteStartFailedEx {
    try {
        //传入的zygoteState为openZygoteSocketIfNeeded(),里面会通过abi来检查是第一个zygote还是第二个
        final BufferedWriter zygoteWriter = zygoteState.mZygoteOutputWriter;
        final DataInputStream zygoteInputStream = zygoteState.mZygoteInputStream;

        zygoteWriter.write(msgStr);  //把应用进程的一些参数写给前面连接的zygote进程,包括前面的processClass ="android.app.ActivityThread"
        zygoteWriter.flush(); //进入Zygote进程,处于阻塞状态, 参考[4.3]

         //从socket中得到zygote创建的应用pid,赋值给 ProcessStartResult的对象
        Process.ProcessStartResult result = new Process.ProcessStartResult();
        result.pid = zygoteInputStream.readInt();
        result.usingWrapper = zygoteInputStream.readBoolean();

        if (result.pid < 0) {
            throw new ZygoteStartFailedEx("fork() failed");
        }

        return result;
    } catch (IOException ex) {
        zygoteState.close();
        Log.e(LOG_TAG, "IO Exception while communicating with Zygote - "
                + ex.toString());
        throw new ZygoteStartFailedEx(ex);
    }
}

4.3 第三阶段 Zygote Fork 应用进程

说明:Zygote的启动过程我们前面有详细讲到过。

SystemServer的AMS服务向启动Home Activity发起一个fork请求,Zygote进程通过Linux的fork函数,孵化出一个新的进程。

由于Zygote进程在启动时会创建Java虚拟机,因此通过fork而创建的Launcher程序进程可以在内部获取一个Java虚拟机的实例拷贝。

fork采用copy-on-write机制,有些类如果不做改变,甚至都不用复制,子进程可以和父进程共享这部分数据,从而省去不少内存的占用。

调用栈如下:

4.3.1 [ZygoteInit.java] main()

说明:Zygote先fork出SystemServer进程,接着进入循环等待,用来接收Socket发来的消息,用来fork出其他应用进程,比如Launcher

源码:

public static void main(String argv[]) {
    ...
    Runnable caller;
    ....
    if (startSystemServer) {
        //Zygote Fork出的第一个进程 SystmeServer
        Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);

        if (r != null) {
            r.run();
            return;
        }
    }
    ...
    //循环等待fork出其他的应用进程,比如Launcher
    //最终通过调用processOneCommand()来进行进程的处理,参考[4.3.2]
    caller = zygoteServer.runSelectLoop(abiList);
    ...
    if (caller != null) {
        caller.run(); //执行返回的Runnable对象,进入子进程
    }
}

4.3.2 [ZygoteConnection.java] processOneCommand()

说明:通过 forkAndSpecialize()来fork出Launcher的子进程,并执行handleChildProc,进入子进程的处理

源码:

Runnable processOneCommand(ZygoteServer zygoteServer) {
    int pid = -1;
    ...
    //Fork子进程,得到一个新的pid
    /fork子进程,采用copy on write方式,这里执行一次,会返回两次
    ///pid=0 表示Zygote  fork子进程成功
    //pid > 0 表示子进程 的真正的PID
	//参考[4.3.3]
    pid = Zygote.forkAndSpecialize(parsedArgs.mUid, parsedArgs.mGid, parsedArgs.mGids,
            parsedArgs.mRuntimeFlags, rlimits, parsedArgs.mMountExternal, parsedArgs.mSeInfo,
            parsedArgs.mNiceName, fdsToClose, fdsToIgnore, parsedArgs.mStartChildZygote,
            parsedArgs.mInstructionSet, parsedArgs.mAppDataDir, parsedArgs.mTargetSdkVersion);
    ...
    if (pid == 0) {
        // in child, fork成功,第一次返回的pid = 0
        ...
        //参考[4.3.7]
        return handleChildProc(parsedArgs, descriptors, childPipeFd,
                parsedArgs.mStartChildZygote);
    } else {
        //in parent
        ...
        childPipeFd = null;
        handleParentProc(pid, descriptors, serverPipeFd);
        return null;
    }
}

4.3.3 [Zygote.java] forkAndSpecialize

说明:主要是调用dalvik中ZygoteHooks的preFrok进行预处理,再调用postForkCommon进行完成的进程fork

源码:

public static int forkAndSpecialize(int uid, int gid, int[] gids, int runtimeFlags,
        int[][] rlimits, int mountExternal, String seInfo, String niceName, int[] fdsToClose,
        int[] fdsToIgnore, boolean startChildZygote, String instructionSet, String appDataDir,
        int targetSdkVersion) {
    ZygoteHooks.preFork(); //参考[4.3.3.1]
	//参考[4.3.5]
	int pid = nativeForkAndSpecialize(
                uid, gid, gids, runtimeFlags, rlimits, mountExternal, seInfo, niceName, fdsToClose,
                fdsToIgnore, startChildZygote, instructionSet, appDataDir);
	...
	//参考[4.3.6]
    ZygoteHooks.postForkCommon();
    return pid;
}

4.3.3.1 [ZygoteHooks.java] preFork()

说明:Zygote进程有4个Daemon子线程分别是 :

HeapTaskDaemon、ReferenceQueueDaemon、FinalizerDaemon、FinalizerWatchdogDaemon

preFork()预处理主要是先停止4个子线程,等待所有的子线程结束,最后完成gc堆的初始化工作

Zygote子线程如下图所示:

源码:

public void preFork() {
    Daemons.stop();	//停止4个Daemon子线程,参考[4.3.3.2]
    waitUntilAllThreadsStopped();	//等待所有子线程结束,参考[4.3.3.3]
    token = nativePreFork();	//完成gc堆的初始化工作,参考[4.3.4]
}

4.3.3.2 [Daemons.java] stop()

说明:此处守护线程Stop方式是先调用目标线程interrrupt()方法,然后再调用目标线程join()方法,等待线程执行完成

停止4个子线程,分别是:Java堆整理线程;引用队列线程;析构线程;析构监控线程

源码:

private static final Daemon[] DAEMONS = new Daemon[] {
    HeapTaskDaemon.INSTANCE,  //Java堆整理线程
    ReferenceQueueDaemon.INSTANCE,  //引用队列线程
    FinalizerDaemon.INSTANCE,//析构线程
    FinalizerWatchdogDaemon.INSTANCE, //析构监控线程
};

public static void stop() {
    for (Daemon daemon : DAEMONS) {
        daemon.stop(); //循环停止线程
    }
}

4.3.3.3 [ZygoteHooks.java] waitUntilAllThreadsStopped()

说明:等待所有子线程结束

源码:

private static void waitUntilAllThreadsStopped() {
    File tasks = new File("/proc/self/task");
	// 当/proc中线程数大于1,就出让CPU直到只有一个线程,才退出循环
    while (tasks.list().length > 1) {
      Thread.yield();
    }
}

4.3.4 [ZygoteHooks.java] nativePreFork()

通过JNI最终调用的是以下方法:

[dalvik_system_ZygoteHooks.cc] ZygoteHooks_nativePreFork()

说明:进行堆的一些预处理

源码:

static jlong ZygoteHooks_nativePreFork(JNIEnv* env, jclass) {
  Runtime* runtime = Runtime::Current();
  CHECK(runtime->IsZygote()) << "runtime instance not started with -Xzygote";

  runtime->PreZygoteFork(); //参考[4.3.4.1]

  //将线程转换为long型并保存到token,该过程是非安全的
  return reinterpret_cast<jlong>(ThreadForEnv(env));
}

4.3.4.1 [runtime.cpp] PreZygoteFork()

说明:堆的初始化工作,属于虚拟机的范畴,想理解的可以深挖一下

源码:

void Runtime::PreZygoteFork() {
  if (GetJit() != nullptr) {
    GetJit()->PreZygoteFork();
  }

  // 初始化堆的操作
  heap_->PreZygoteFork();
}

4.3.5 [Zygote.java] nativeForkAndSpecialize()

通过JNI最终调用的是以下方法:

[com_android_internal_os_Zygote.cpp] com_android_internal_os_Zygote_nativeForkAndSpecialize

说明: fork 子进程

源码:

static jint com_android_internal_os_Zygote_nativeForkAndSpecialize(...) {
	...
	//fork 应用进程,得到新的pid,fork()操作会有两次返回,第一次返回成功,pid=0
	//第二次返回真正的pid
	//参考[4.3.5.1]
	pid_t pid = ForkCommon(env, false, fds_to_close, fds_to_ignore);
	if (pid == 0) {
	  //上面第一次fork成功
	  //参考[4.3.5.2]
      SpecializeCommon(env, uid, gid, gids, runtime_flags, rlimits,
                       capabilities, capabilities,
                       mount_external, se_info, nice_name, false,
                       is_child_zygote == JNI_TRUE, instruction_set, app_data_dir);
    }
    return pid;
}

4.3.5.1 [com_android_internal_os_Zygote.cpp] ForkCommon()

说明:调用系统的fork()进行 应用进程的孵化操作,采用copy-on-write的机制,使得应用进程与Zygote共享部分数据,减少内存的占用

源码:

static pid_t ForkCommon(JNIEnv* env, bool is_system_server,..) {
  //设置子进程的signal
  SetSignalHandlers();
  ...
  //fork子进程,这里执行一次,会返回两次
  //pid=0 表示Zygote  fork SystemServer这个子进程成功
  //pid > 0 表示SystemServer 的真正的PID
  pid_t pid = fork();
  if (pid == 0) {
     //进入子进程
    PreApplicationInit();
    // 关闭并清除文件描述符
    DetachDescriptors(env, fds_to_close, fail_fn);
    ClearUsapTable();
	...
  } else {
    ALOGD("Forked child process %d", pid);
  }
  return pid;
}

4.3.5.2 [com_android_internal_os_Zygote.cpp]   SpecializeCommon()

说明:进行进程的一些资源处理,selinux权限处理,并调用Zygote的callPostForkChildHooks()

源码:

static void SpecializeCommon(...){
	...
  if (!is_system_server && getuid() == 0) {
    //对于非system_server子进程,则创建进程组
    const int rc = createProcessGroup(uid, getpid());
	...
  }
  SetGids(env, gids, fail_fn);  //设置设置group
  SetRLimits(env, rlimits, fail_fn); //设置资源limit
  ...
   //selinux上下文
  if (selinux_android_setcontext(uid, is_system_server, se_info_ptr, nice_name_ptr) == -1) {
	...
  }
  ...
  //设置子进程的signal信号处理函数为默认函数
  UnsetChldSignalHandler();
   //等价于调用zygote.callPostForkChildHooks(), 参考[4.3.5.3]
  env->CallStaticVoidMethod(gZygoteClass, gCallPostForkChildHooks, runtime_flags,
                            is_system_server, is_child_zygote, managed_instruction_set);
}

4.3.5.3 [Zygote.java]  callPostForkChildHooks()

说明:JAVA堆线程的一些处理

源码:

    private static void callPostForkChildHooks(int runtimeFlags, boolean isSystemServer,
            boolean isZygote, String instructionSet) {
        ZygoteHooks.postForkChild(runtimeFlags, isSystemServer, isZygote, instructionSet);
    }

[ZygoteHooks.java] postForkChild 
public void postForkChild(int runtimeFlags, boolean isSystemServer, boolean isZygote,
        String instructionSet) {
	//JNI调用到 ZygoteHooks_nativePostForkChild()
    nativePostForkChild(token, runtimeFlags, isSystemServer, isZygote, instructionSet);
    Math.setRandomSeedInternal(System.currentTimeMillis());
}

[dalvik_system_ZygoteHooks.cc] ZygoteHooks_nativePostForkChild()
static void ZygoteHooks_nativePostForkChild(...) {
  Thread* thread = reinterpret_cast<Thread*>(token);
  //设置新进程的主线程id
  thread->InitAfterFork();
  ...
   if (instruction_set != nullptr && !is_system_server) {
	...
	//调用runtime的InitNonZygoteOrPostFork()进行处理
    Runtime::Current()->InitNonZygoteOrPostFork(
        env, is_system_server, action, isa_string.c_str());
  } else {
    Runtime::Current()->InitNonZygoteOrPostFork(
        env,
        is_system_server,
        Runtime::NativeBridgeAction::kUnload,
        /*isa*/ nullptr,
        profile_system_server);
  }
}

创建JAVA的线程池,设置信号处理,启动JDWP线程

[runtime.cc] InitNonZygoteOrPostFork()
void Runtime::InitNonZygoteOrPostFork(...) {
  is_zygote_ = false;

  if (is_native_bridge_loaded_) {
    switch (action) {
      case NativeBridgeAction::kUnload:
        UnloadNativeBridge();  //卸载用于跨平台的桥连库
        is_native_bridge_loaded_ = false;
        break;

      case NativeBridgeAction::kInitialize:
        InitializeNativeBridge(env, isa); //初始化用于跨平台的桥连库
        break;
    }
  }

  //创建Java堆处理的线程池
  heap_->CreateThreadPool();
  //重置gc性能数据,以保证进程在创建之前的GCs不会计算到当前app上。
  heap_->ResetGcPerformanceInfo();
  ...
  StartSignalCatcher();//设置信号处理函数

  //启动JDWP线程,当命令debuger的flags指定"suspend=y"时,则暂停runtime
  ScopedObjectAccess soa(Thread::Current());
  GetRuntimeCallbacks()->StartDebugger();
}

4.3.6 [ZygoteHooks.java] postForkCommon()

说明:在fork新进程后,启动Zygote的4个Daemon线程,java堆整理,引用队列,以及析构线程。

源码:

public void postForkCommon() {
    Daemons.startPostZygoteFork();
    nativePostZygoteFork();
}

启动Zygote的4个新的子线程

[Daemons.java]
private static final Daemon[] DAEMONS = new Daemon[] {
    HeapTaskDaemon.INSTANCE,         //Java堆整理线程
    ReferenceQueueDaemon.INSTANCE,   //引用队列线程
    FinalizerDaemon.INSTANCE,        //析构线程
    FinalizerWatchdogDaemon.INSTANCE, //析构监控线程
};

public static void startPostZygoteFork() {
    postZygoteFork = true;
    for (Daemon daemon : DAEMONS) {
        daemon.startPostZygoteFork();
    }
}

4.3.7 [ZygoteConnection.java] handleChildProc()

说明:进行子进程的操作,最终获得需要执行的ActivityThread的main()

源码:

private Runnable handleChildProc(ZygoteArguments parsedArgs, FileDescriptor[] descriptors,
        FileDescriptor pipeFd, boolean isZygote) {
    ...
    if (parsedArgs.mInvokeWith != null) {
        ...
        throw new IllegalStateException("WrapperInit.execApplication unexpectedly returned");
    } else {
        if (!isZygote) {
            // App进程将会调用到这里,执行目标类的main()方法
            return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,
                    parsedArgs.mRemainingArgs, null /* classLoader */);
        } else {
            return ZygoteInit.childZygoteInit(parsedArgs.mTargetSdkVersion,
                    parsedArgs.mRemainingArgs, null /* classLoader */);
        }
    }
}

zygoteInit 进行一些环境的初始化、启动Binder进程等操作

public static final Runnable zygoteInit(int targetSdkVersion, String[] argv,
        ClassLoader classLoader) {
    RuntimeInit.commonInit(); //初始化运行环境 
    ZygoteInit.nativeZygoteInit(); //启动Binder线程池 
     //调用程序入口函数  
    return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
}

把之前传来的"android.app.ActivityThread" 传递给findStaticMain

protected static Runnable applicationInit(int targetSdkVersion, String[] argv,
        ClassLoader classLoader) {
    ...
    // startClass: 如果AMS通过socket传递过来的是 ActivityThread
    return findStaticMain(args.startClass, args.startArgs, classLoader);
}

通过反射,拿到ActivityThread的main()方法

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 {
        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);
    }
    return new MethodAndArgsCaller(m, argv);
}

把反射得来的ActivityThread main()入口返回给ZygoteInit的main,通过caller.run()进行调用

static class MethodAndArgsCaller 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;
    }

    //调用ActivityThread的main()
    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);
        }
    }
}

至此,Zygote fork进程的操作全部完成,下一步进入JAVA世界,进行真正的Activity的启动流程。

4.4 第四阶段 进入应用进程,启动Activity的onCreate()

调用栈如下:

4.4.1 [ActivityThread.java] main()

说明: 主线程处理, 创建ActivityThread对象,调用attach进行处理,最终进入Looper循环

源码:

public static void main(String[] args) {
    // 安装选择性的系统调用拦截
    AndroidOs.install();
	...
	//主线程处理
    Looper.prepareMainLooper();
	...
	
	//之前SystemServer调用attach传入的是true,这里到应用进程传入false就行
    ActivityThread thread = new ActivityThread();
    thread.attach(false, startSeq);
	...
	//一直循环,如果退出,说明程序关闭
    Looper.loop();

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

调用ActivityThread的attach进行处理

   private void attach(boolean system, long startSeq) {
    sCurrentActivityThread = this;
    mSystemThread = system;
    if (!system) {
        //应用进程启动,走该流程
		...
        RuntimeInit.setApplicationObject(mAppThread.asBinder());
         //获取AMS的本地代理类
        final IActivityManager mgr = ActivityManager.getService();
        try {
            //通过Binder调用AMS的attachApplication方法,参考[4.4.2]
            mgr.attachApplication(mAppThread, startSeq);
        } catch (RemoteException ex) {
            throw ex.rethrowFromSystemServer();
        }
		...
    } else {
        //通过system_server启动ActivityThread对象
        ...
    }

    // 为 ViewRootImpl 设置配置更新回调,
  //当系统资源配置(如:系统字体)发生变化时,通知系统配置发生变化
    ViewRootImpl.ConfigChangedCallback configChangedCallback
            = (Configuration globalConfig) -> {
        synchronized (mResourcesManager) {
			...
        }
    };
    ViewRootImpl.addConfigCallback(configChangedCallback);
}

4.4.2  [ActivityManagerService.java] attachApplication()

说明:清除一些无用的记录,最终调用ActivityStackSupervisor.java的 realStartActivityLocked(),进行Activity的启动

源码:

public final void attachApplication(IApplicationThread thread, long startSeq) {
    synchronized (this) {
		//通过Binder获取传入的pid信息
        int callingPid = Binder.getCallingPid();
        final int callingUid = Binder.getCallingUid();
        final long origId = Binder.clearCallingIdentity();
        attachApplicationLocked(thread, callingPid, callingUid, startSeq);
        Binder.restoreCallingIdentity(origId);
    }
}
private final boolean attachApplicationLocked(IApplicationThread thread,
        int pid, int callingUid, long startSeq) {
	...
    //如果当前的Application记录仍然依附到之前的进程中,则清理掉
    if (app.thread != null) {
        handleAppDiedLocked(app, true, true);
    }·

    //mProcessesReady这个变量在AMS的 systemReady 中被赋值为true,
    //所以这里的normalMode也为true
    boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
	...
    //上面说到,这里为true,进入StackSupervisor的attachApplication方法
    //去真正启动Activity
    if (normalMode) {
		...
			//调用ATM的attachApplication(),最终层层调用到ActivityStackSupervisor.java的 realStartActivityLocked()
			//参考[4.4.3]
            didSomething = mAtmInternal.attachApplication(app.getWindowProcessController());
		...
    }
	...
    return true;
}

4.4.3 [ActivityStackSupervisor.java]  realStartActivityLocked()

说明:真正准备去启动Activity,通过clientTransaction.addCallback把LaunchActivityItem的obtain作为回调参数加进去,再调用

ClientLifecycleManager.scheduleTransaction()得到LaunchActivityItem的execute()方法进行最终的执行

参考上面的第四阶段的调用栈流程:

源码:

 boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
        boolean andResume, boolean checkConfig) throws RemoteException {
     // 直到所有的 onPause() 执行结束才会去启动新的 activity
    if (!mRootActivityContainer.allPausedActivitiesComplete()) {
		...
        return false;
    }
	try {
            // Create activity launch transaction.
            // 添加 LaunchActivityItem
            final ClientTransaction clientTransaction = ClientTransaction.obtain(
                    proc.getThread(), r.appToken);
			//LaunchActivityItem.obtain(new Intent(r.intent)作为回调参数
            clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
                    System.identityHashCode(r), r.info,
                    // TODO: Have this take the merged configuration instead of separate global
                    // and override configs.
                    mergedConfiguration.getGlobalConfiguration(),
                    mergedConfiguration.getOverrideConfiguration(), r.compat,
                    r.launchedFromPackage, task.voiceInteractor, proc.getReportedProcState(),
                    r.icicle, r.persistentState, results, newIntents,
                    dc.isNextTransitionForward(), proc.createProfilerInfoIfNeeded(),
                            r.assistToken));

			...
			// 设置生命周期状态
            final ActivityLifecycleItem lifecycleItem;
            if (andResume) {
                lifecycleItem = ResumeActivityItem.obtain(dc.isNextTransitionForward());
            } else {
                lifecycleItem = PauseActivityItem.obtain();
            }
            clientTransaction.setLifecycleStateRequest(lifecycleItem);

            // Schedule transaction.
            // 重点关注:调用 ClientLifecycleManager.scheduleTransaction(),得到上面addCallback的LaunchActivityItem的execute()方法
			//参考[4.4.4]
            mService.getLifecycleManager().scheduleTransaction(clientTransaction);

        } catch (RemoteException e) {
            if (r.launchFailed) {
                 // 第二次启动失败,finish activity
                stack.requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null,
                        "2nd-crash", false);
                return false;
            }
            // 第一次失败,重启进程并重试
            r.launchFailed = true;
            proc.removeActivity(r);
            throw e;
        }
    } finally {
        endDeferResume();
    }
	...
    return true;
}

4.4.4 [TransactionExecutor.java] execute()

说明:执行之前realStartActivityLocked()中的 clientTransaction.addCallback

调用栈:

源码:

  public void execute(ClientTransaction transaction) {
	...
     // 执行 callBack,参考上面的调用栈,执行回调方法,
	 //最终调用到ActivityThread的handleLaunchActivity()参考[4.4.5]
    executeCallbacks(transaction);

     // 执行生命周期状态
    executeLifecycleState(transaction);
    mPendingActions.clear();
}

4.4.5 [ActivityThread.java] handleLaunchActivity()

说明:主要干了两件事,第一件:初始化WindowManagerGlobal;第二件:调用performLaunchActivity方法

源码:

public Activity handleLaunchActivity(ActivityClientRecord r,
        PendingTransactionActions pendingActions, Intent customIntent) {
	...
	//初始化WindowManagerGlobal
    WindowManagerGlobal.initialize();
	...
	//调用performLaunchActivity,来处理Activity,参考[4.4.6]
    final Activity a = performLaunchActivity(r, customIntent);
	..
    return a;
}

4.4.6 [ActivityThread.java] performLaunchActivity()

说明:获取ComponentName、Context,反射创建Activity,设置Activity的一些内容,比如主题等;

最终调用callActivityOnCreate()来执行Activity的onCreate()方法

源码:

  private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
     // 获取 ComponentName
    ComponentName component = r.intent.getComponent();
	...
     // 获取 Context
    ContextImpl appContext = createBaseContextForActivity(r);
    Activity activity = null;
    try {
         // 反射创建 Activity
        java.lang.ClassLoader cl = appContext.getClassLoader();
        activity = mInstrumentation.newActivity(
                cl, component.getClassName(), r.intent);
        StrictMode.incrementExpectedActivityCount(activity.getClass());
        r.intent.setExtrasClassLoader(cl);
        r.intent.prepareToEnterProcess();
        if (r.state != null) {
            r.state.setClassLoader(cl);
        }
    } catch (Exception e) {
		...
    }

    try {
        // 获取 Application
        Application app = r.packageInfo.makeApplication(false, mInstrumentation);
        if (activity != null) {
			...
			//Activity的一些处理
            activity.attach(appContext, this, getInstrumentation(), r.token,
                    r.ident, app, r.intent, r.activityInfo, title, r.parent,
                    r.embeddedID, r.lastNonConfigurationInstances, config,
                    r.referrer, r.voiceInteractor, window, r.configCallback,
                    r.assistToken);

            if (customIntent != null) {
                activity.mIntent = customIntent;
            }
			...
            int theme = r.activityInfo.getThemeResource();
            if (theme != 0) {
              // 设置主题
                activity.setTheme(theme);
            }

            activity.mCalled = false;
            // 执行 onCreate()
            if (r.isPersistable()) {
                mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
            } else {
                mInstrumentation.callActivityOnCreate(activity, r.state);
            }
			...
            r.activity = activity;
        }
		//当前状态为ON_CREATE
        r.setState(ON_CREATE);
		...
    } catch (SuperNotCalledException e) {
        throw e;
    } catch (Exception e) {
		...
    }
    return activity;
}

callActivityOnCreate先执行activity onCreate的预处理,再去调用Activity的onCreate,最终完成Create创建后的内容处理

public void callActivityOnCreate(Activity activity, Bundle icicle,
        PersistableBundle persistentState) {
    prePerformCreate(activity); //activity onCreate的预处理
    activity.performCreate(icicle, persistentState);//执行onCreate()
    postPerformCreate(activity); //activity onCreate创建后的一些信息处理
}

performCreate()主要调用Activity的onCreate()

final void performCreate(Bundle icicle, PersistableBundle persistentState) {
	...
    if (persistentState != null) {
        onCreate(icicle, persistentState);
    } else {
        onCreate(icicle);
    }
	...
}

  至此,看到了我们最熟悉的Activity的onCreate(),应用启动的启动完成,应用程序被真正的调用起来。

5.总结

    通过上面一系列的流程,我们理解了应用进程的创建流程,以及Zygote fork这些应用进程的流程。

主要分为4步完成:

  1. 点击桌面的图标,Launcher调用系统的startActivity进行启动Activity,此时的动作在Launcher进程中

  2. 通过Binder向SystemServer进行发送消息,让ATM\AMS 进行Activity的处理,组装message,通过socket发送给Socket,此时动作在SystemServer进程中

  3. Zygote收到SystemServer发来的消息,进行消息拆分,再调用系统的fork()函数,进行进行孵化操作,此时动作在Zygote进程中

  4. 进入ActivityThread的main(),完成最终应用进程的的onCreate操作,该步动作处于新创建的应用进程中

下一节想来看一看PMS的启动流程。

微信公众号:大猫玩程序

发布了11 篇原创文章 · 获赞 25 · 访问量 7921

猜你喜欢

转载自blog.csdn.net/yiranfeng/article/details/103812553