当前位置:首页 > CN2资讯 > 正文内容

windows android 进程 安卓10进程管理

10小时前CN2资讯

 

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()来创建一个新的线程。

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

 

进程线程的区别

  • 地址空间:同一进程的线程共享本进程的地址空间,而进程之间则是独立的地址空间。
  • 资源拥有:同一进程内的线程共享本进程的资源,但是进程之间的资源是独立的。
  • 一个进程崩溃后,在保护模式下不会对其他进程产生影响,但是一个线程崩溃整个进程都死掉。所以多进程要比多线程健壮。
  • 进程切换时,消耗的资源大,效率高。所以涉及到频繁的切换时,使用线程要好于进程。同样如果要求同时进行并且又要共享某些变量的并发操作,只能用线程不能用进程。
  • 执行过程:每个独立的进程有一个程序运行的入口、顺序执行序列和程序入口。但是线程不能独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。
  • 线程是处理器调度的基本单位,但是进程不是。
  • 两者均可并发执行。
     
  • 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/ /art/runtime/native/dalvik_system_ZygoteHooks.cc /art/runtime/ /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.源码分析

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

  • 点击桌面的图标,Launcher调用系统的startActivity进行启动Activity,此时的动作在Launcher进程中
  • ATM\AMS 进行Activity的处理,组装message,通过socket发送给Socket
  • Zygote收到SystemServer发来的消息,进行消息拆分,再调用系统的fork()函数,进行进行孵化操作。
  • 进入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, .applicationInfo, knownToBeDead, "activity", r.intent.getComponent()); .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 =".ActivityThread",通过Zygote进程来Fork出一个新的进程,并执行 ".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 =".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线程

     

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

    把之前传来的".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), , // 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步完成:

  • 点击桌面的图标,Launcher调用系统的startActivity进行启动Activity,此时的动作在Launcher进程中
  • 通过Binder向SystemServer进行发送消息,让ATM\AMS 进行Activity的处理,组装message,通过socket发送给Socket,此时动作在SystemServer进程中
  • Zygote收到SystemServer发来的消息,进行消息拆分,再调用系统的fork()函数,进行进行孵化操作,此时动作在Zygote进程中
  • 进入ActivityThread的main(),完成最终应用进程的的onCreate操作,该步动作处于新创建的应用进程中
  •  

      你可能想看:

      扫描二维码推送至手机访问。

      版权声明:本文由皇冠云发布,如需转载请注明出处。

      本文链接:https://www.idchg.com/info/28171.html

      分享给朋友:

      “windows android 进程 安卓10进程管理” 的相关文章

      如何利用VPS挖矿赚钱:低成本高收益的加密货币挖矿指南

      VPS挖矿的基本概念 VPS挖矿是一种利用虚拟专用服务器(VPS)的计算资源进行加密货币挖矿的方式。VPS通常用于托管网站或运行应用程序,但它的计算能力也可以被用来执行挖矿算法。挖矿本质上是通过解决复杂的数学问题来验证交易并创建新的加密货币区块,作为回报,矿工会获得一定数量的加密货币。VPS挖矿特别...

      全球主机交流论坛:提升技术的最佳平台

      全球主机论坛概述 在当今数字化时代,全球主机论坛扮演着越来越重要的角色。这些论坛不仅是技术爱好者的聚集地,更是为需要域名、主机、VPS和服务器信息的用户提供了一个交流的平台。我作为一名站长,经常在这样的论坛上交流经验、获取灵感和解决技术难题,论坛的存在极大地丰富了我的网络建设之旅。 主机论坛的定义其...

      CloudCone VPS评测:高性能与灵活计费方案的完美结合

      在谈论CloudCone VPS之前,让我给你介绍一下这家服务商。CloudCone成立于2017年,起源于美国,主要是在洛杉矶的MultaCom机房提供云主机和VPS服务。自创立以来,CloudCone逐步发展壮大,不断优化和提升其服务质量,为用户提供便捷的云计算解决方案。可以说,CloudCon...

      Virmach Coupons: 轻松获取超值优惠,优化你的VPS选择

      Virmach成立于2014年,作为一家美国VPS服务商,在业内享有良好的声誉。它的总部位于加利福尼亚州洛杉矶,正是这样得天独厚的地理位置让它能迅速成长并服务全球用户。到现在为止,Virmach已经发展成为一家提供各种配置和价格方案的服务商,特别以低价VPS而闻名,吸引了大量希望降低运营成本的个人和...

      甲骨文云账号如何注销:详尽步骤与注意事项

      甲骨文云账号注销流程 注销甲骨文云账号的流程其实并不复杂,但有几个关键步骤需要认真对待。整个过程主要分为几个部分,包括登录甲骨文云控制台、发起注销请求、查看注销请求状态,以及最后的等待和确认删除。 1.1 甲骨文云控制台的登录 进入甲骨文云控制台的第一步,就是要登录到你的账号。打开浏览器,访问甲骨文...

      Virtono:高性价比的虚拟主机与云服务器解决方案

      在这个信息化迅猛发展的时代,虚拟主机与服务器服务需求越来越高。而提到这个领域,其中有一家备受注目的公司,那就是Virtono。成立于2014年的Virtono,凭借其卓越的产品与服务迅速在全球市场上崭露头角。对于我来说,Virtono的故事不仅仅代表着一家公司,更是一段不断创新与发展的旅程。 Vir...