Android应用程序进程启动过程(前篇)

本文详细探讨了Android7.0中应用程序进程的启动过程,从概述到创建步骤,涉及ActivityManagerService如何请求Zygote启动进程,再到Zygote如何通过fork创建应用进程,最终解释了如何启动ActivityThread,实现应用进程的初始化。
摘要由CSDN通过智能技术生成

相关文章
Android系统架构与系统源码目录
Android系统启动流程(一)解析init进程启动过程
Android系统启动流程(二)解析Zygote进程启动过程
Android系统启动流程(三)解析SyetemServer进程启动过程
Android系统启动流程(四)Launcher启动过程与系统启动流程

前言

在此前我讲过Android系统的启动流程,系统启动后,我们就比较关心应用程序是如何启动的,这一篇我们来一起学习Android7.0 应用程序进程启动过程,需要注意的是“应用程序进程启动过程”,而不是应用程序启动过程。关于应用程序启动过程,我会在后续系列的文章中讲到。希望阅读这篇文章前先阅读本文列出的相关文章,要不你一脸蒙蔽,就别怪我了。

1.应用程序进程概述

要想启动一个应用程序,首先要保证这个应用程序所需要的应用程序进程已经被启动。ActivityManagerService在启动应用程序时会检查这个应用程序需要的应用程序进程是否存在,不存在就会请求Zygote进程将需要的应用程序进程启动。在Android系统启动流程(二)解析Zygote进程启动过程这篇文章中,我提到了Zygote的Java框架层中,会创建一个Server端的Socket,这个Socket用来等待ActivityManagerService来请求Zygote来创建新的应用程序进程的。我们知道Zygote进程通过fock自身创建的应用程序进程,这样应用程序程序进程就会获得Zygote进程在启动时创建的虚拟机实例。当然,在应用程序创建过程中除了获取虚拟机实例,还可以获得Binder线程池和消息循环,这样运行在应用进程中应用程序就可以方便的使用Binder进行进程间通信以及消息处理机制了。关于Binder线程池和消息循环是如何启动或者创建的会在下一篇文章给出答案。先给出应用程序进程启动过程的时序图,然后对每一个步骤进行详细分析,如下图所示。
Android应用进程启动过程.png

2.应用程序进程创建过程

发送创建应用程序进程请求

ActivityManagerService会通过调用startProcessLocked函数来向Zygote进程发送请求,如下所示。
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

  private final void startProcessLocked(ProcessRecord app, String hostingType,
            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
        ...
        try {
            try {
                final int userId = UserHandle.getUserId(app.uid);
                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
            } catch (RemoteException e) {
                throw e.rethrowAsRuntimeException();
            }

            int uid = app.uid;//1
            int[] gids = null;
            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
            if (!app.isolated) {
              ...
              /**
              * 2 对gids进行创建和赋值
              */
                if (ArrayUtils.isEmpty(permGids)) {
                    gids = new int[2];
                } else {
                    gids = new int[permGids.length + 2];
                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
                }
                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
            }

           ...
            if (entryPoint == null) entryPoint = "android.app.ActivityThread";//3
            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
                    app.processName);
            checkTime(startTime, "startProcess: asking zygote to start proc");
            /**
            * 4
            */
            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);
           ...
        } catch (RuntimeException e) {
          ...
        }
    }
   ...
    }

在注释1处的达到创建应用程序进程的用户ID,在注释2处对用户组ID:gids进行创建和赋值。注释3处如果entryPoint 为null则赋值为”android.app.ActivityThread”。在注释4处调用Process的start函数,将此前得到的应用程序进程用户ID和用户组ID传进去,第一个参数entryPoint我们得知是”android.app.ActivityThread”,后文会再次提到它。接下来我们来查看Process的start函数,如下所示。
frameworks/base/core/java/android/os/Process.java

public 
  • 14
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值