ActivityManagerService启动学习

ActivityManagerService启动学习

简介

学习android高级课程的时候遇到几个问题,就是如何启动一个app。activity与ActivityManagerService通讯流程?Activity究竟是什么?

Activity究竟是什么?

个人理解是一个状态。当前页面处于什么状态。而绘制是通过WindowManagerService来进行。状态控制通过ActivityManagerService来进行。而activity可以理解为一个代理。

ActivityManagerService

要剖析ActivityManagerService的作用,第一个就是先弄明白他是如何启动的

AMS启动流程

android在启动的时候会初始化init进程,之后通过init进程启动zygoto进程,Android中大多数应用进程和系统进程都是通过zygoto进程生成的。上面的文章已经讲解了如何去fork一个进程。这里看一下AMS的启动流程
首先zygoto进程是通过zygotoinit.java启动的

先看一下zygotoinitmain方法,发现他创建了ZygoteServer,接着初始化ZygoteHooks,接着调用forkSystemServer进行fork,发现他其实调用的是ZygoteforkSystemServer方法

class zygotoinit{
   

   @UnsupportedAppUsage
    public static void main(String argv[]) {
   
        // 这里创建ZygoteServer,是创建一个serversocket
        ZygoteServer zygoteServer = new ZygoteServer();
        // Mark zygote start. This ensures that thread creation will throw
        // an error.
        ZygoteHooks.startZygoteNoThreadCreation();
        // Zygote goes into its own process group.
        Os.setpgid(0, 0);
        zygoteServer.createZygoteSocket(socketName);
        Zygote.createBlastulaSocket(blastulaSocketName);
        Zygote.getSocketFDs(socketName.equals(ZygoteProcess.ZYGOTE_SOCKET_NAME));
        // 这里进行fork
        if (startSystemServer) {
   
                Runnable r = forkSystemServer(abiList, socketName, zygoteServer);

                // {@code r == null} in the parent (zygote) process, and {@code r != null} in the
                // child (system_server) process.
                if (r != null) {
   
                    r.run();
                    return;
                }
            }
       }

        // 进行fork操作
    private static Runnable forkSystemServer(String abiList, String socketName,
            ZygoteServer zygoteServer) {
   
        long capabilities = posixCapabilitiesAsBits(
                OsConstants.CAP_IPC_LOCK,
                OsConstants.CAP_KILL,
                OsConstants.CAP_NET_ADMIN,
                OsConstants.CAP_NET_BIND_SERVICE,
                OsConstants.CAP_NET_BROADCAST,
                OsConstants.CAP_NET_RAW,
                OsConstants.CAP_SYS_MODULE,
                OsConstants.CAP_SYS_NICE,
                OsConstants.CAP_SYS_PTRACE,
                OsConstants.CAP_SYS_TIME,
                OsConstants.CAP_SYS_TTY_CONFIG,
                OsConstants.CAP_WAKE_ALARM,
                OsConstants.CAP_BLOCK_SUSPEND
        );
         try {
   
            /* Request to fork the system server process */
            pid = Zygote.forkSystemServer(
                    parsedArgs.mUid, parsedArgs.mGid,
                    parsedArgs.mGids,
                    parsedArgs.mRuntimeFlags,
                    null,
                    parsedArgs.mPermittedCapabilities,
                    parsedArgs.mEffectiveCapabilities);
        } catch (IllegalArgumentException ex) {
   
            throw new RuntimeException(ex);
        }

        /* For child process */
        if (pid == 0) {
   
            if (hasSecondZygote(abiList)) {
   
                waitForSecondaryZygote(socketName);
            }

            zygoteServer.closeServerSocket();
            return handleSystemServerProcess(parsedArgs);
        }

        return null;
    }
    }


ZygoteforkSystemServer调用了nativeForkSystemServer方法,这是一个native方法,接着调用ZygoteHooks.postForkCommon(),看一下两个方法的具体实现

class Zygote{
   

    public static int forkSystemServer(int uid, int gid, int[] gids, int runtimeFlags,
            int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) {
   
        ZygoteHooks.preFork();
        // Resets nice priority for zygote process.
        resetNicePriority();
        int pid = nativeForkSystemServer(
                uid, gid, gids, runtimeFlags, rlimits,
                permittedCapabilities, effectiveCapabilities);
        // Enable tracing as soon as we enter the system_server.
        if (pid == 0) {
   
            Trace.setTracingEnabled(true, runtimeFlags);
        }
        ZygoteHooks.postForkCommon();
        return pid;
    }
}

可以发现在他的jnif方法中调用了ForkCommon方法,前面的介绍,如果是子进程,他的返回id不是0,如果是当前进程则返回fork进程的id。


static jint com_android_internal_os_Zygote_nativeForkSystemServer(
        JNIEnv* env, jclass, uid_t uid, gid_t gid, jintArray gids,
        jint runtime_flags, jobjectArray rlimits, jlong permitted_capabilities,
        jlong effective_capabilities) {
   
  std::vector<int> fds_to_close(MakeBlastulaPipeReadFDVector()),
                   fds_to_ignore(fds_to_close);

  fds_to_close.push_back(gBlastulaPoolSocketFD);

  if (gBlastulaPoolEventFD != -1) {
   
    fds_to_close.push_back(gBlastulaPoolEventFD);
    fds_to_ignore.push_back(gBlastulaPoolEventFD);
  }
    //这里fork进程
  pid_t pid = ForkCommon(env, true,
                         fds_to_close,
                         fds_to_ignore);
  //如果是子进程
  if (pid == 0) {
   
      SpecializeCommon(env, uid, gid, gids, runtime_flags, rlimits,
                       permitted_capabilities, effective_capabilities,
                       MOUNT_EXTERNAL_DEFAULT, nullptr, nullptr, true,
                       false, nullptr, nullptr);
  // 如果是父进程                     
  } else if (pid > 0) {
   
      // The zygote process checks whether the child process has died or not.
      ALOGI("System server process %d has been created", pid);
      gSystemServerPid = pid;
      // There is a slight window that the system server process has crashed
      // but it went unnoticed because we haven't published its pid yet. So
      // we recheck here just to make sure that all is well.
      int status;
      if (waitpid(pid, &status, WNOHANG) == pid) {
   
          ALOGE("System server process %d has died. Restarting Zygote!", pid);
          RuntimeAbort(env, __LINE__, "System server process has died. Restarting Zygote!");
      }

      if (UsePerAppMemcg()) {
   
          // Assign system_server to the correct memory cgroup.
          // Not all devices mount memcg so check if it is mounted first
          // to avoid unnecessarily printing errors and denials in the logs.
          if (!SetTaskProfiles(pid, std::vector<std::string>{
   "SystemMemoryProcess"})) {
   
              ALOGE("couldn't add process %d into system memcg group", pid);
          }
      }
  }
  return pid;
}


// Utility routine to specialize a zygote child process.
static void SpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArray gids,
                             jint runtime_flags, jobjectArray rlimits,
                             jlong permitted_capabilities, jlong effective_capabilities,
                             jint mount_external, jstring managed_se_info,
                             jstring managed_nice_name, bool is_system_server,
                             bool is_child_zygote, jstring managed_instruction_set,
                             jstring managed_app_data_dir) {
   
  const char* process_name = is_system_server ? "system_server" : "zygote";
  auto fail_fn = std::bind(ZygoteFailure, env, process_name, managed_nice_name, _1);
  auto extract_fn = std::bind(ExtractJString, env, process_name, managed_nice_name, _1);

  auto se_info = extract_fn(managed_se_info);
  auto nice_name = extract_fn(managed_nice_name);
  auto instruction_set = extract_fn(managed_instruction_set);
  auto app_data_dir = extract_fn(managed_app_data_dir);

  // Keep capabilities across UID change, unless we're staying root.
  if (uid != 0) {
   
    EnableKeepCapabilities(fail_fn);
  }

  SetInheritable(permitted_capabilities, fail_fn);

  DropCapabilitiesBoundingSet(fail_fn);

  bool use_native_bridge = !is_system_server &&
                           instruction_set.has_value() &&
                           android::NativeBridgeAvailable() &&
                           android::NeedsNativeBridge(instruction_set.value().c_str());

  if (use_native_bridge && !app_data_dir.has_value()) {
   
    // The app_data_dir variable should never be empty if we need to use a
    // native bridge.  In general, app_data_dir will never be empty for normal
    // applications.  It can only happen in special cases (for isolated
    // processes which are not associated with any app).  These are launched by
    // the framework and should not be emulated anyway.
    use_native_bridge = false;
    ALOGW("Native bridge will not be used because managed_app_data_dir == nullptr.");
  }
//进行fork
// Utility routine to fork a process from the zygote.
static pid_t ForkCommon(JNIEnv* env, bool is_system_server,
                        const std::vector<int>& fds_to_close,
                        const std::vector<int>& fds_to_ignore) {
   
  SetSignalHandlers();

  // Curry a failure function.
  auto fail_fn = std::bind(ZygoteFailure, env, is_system_server ? "system_server" : "zygote",
                           nullptr, _1);

  // Temporarily block SIGCHLD during forks. The SIGCHLD handler might
  // log, which would result in the logging FDs we close being reopened.
  // This would cause failures because the FDs are not whitelisted.
  //
  // Note that the zygote process is single threaded at this point.
  BlockSignal(SIGCHLD, fail_fn);

  // Close any logging related FDs before we start evaluating the list of
  // file descriptors.
  __android_log_close();
  stats_log_close();

  // If this is the first fork for this zygote, create the open FD table.  If
  // it isn't, we just need to check whether the list of open files has changed
  // (and it shouldn't in the normal case).
  if (gOpenFdTable == nullptr) {
   
    gOpenFdTable = FileDescriptorTable::Create(fds_to_ignore, fail_fn);
  } else {
   
    gOpenFdTable->Restat(fds_to_ignore, fail_fn);
  }

  android_fdsan_error_level fdsan_error_level = android_fdsan_get_error_level();
    // 关键的地方来了,,这里进行了fork操作
  pid_t pid = fork();

  if (pid == 0) {
   
    // The child process.
    PreApplicationInit();

    // Clean up any descriptors which must be closed immediately
    DetachDescriptors(env, fds_to_close, fail_fn);

    // Re-open all remaining open file descriptors so that they aren't shared
    // with the zygote across a fork.
    gOpenFdTable->ReopenOrDetach(fail_fn);

    // Turn fdsan back on.
    android_fdsan_set_error_level(fdsan_error_level);
  } else {
   
    ALOGD("Forked child process %d", pid);
  }

  // We blocked SIGCHLD prior to a fork, we unblock it here.
  UnblockSignal(SIGCHLD, fail_fn);

  return pid;
}

fork完成之后执行这个方法ZygoteHooks.postForkCommon();

class ZygoteHooks{
   

    @libcore.api.CorePlatformApi
    public static void postForkCommon() {
   
        // 启动守护进程
        Daemons.startPostZygoteFork();
        nativePostZygoteFork();
    }
}

接着调用了ZygoteHooks.cpp中的ZygoteHooks_nativePostZygoteFork


static void ZygoteHooks_nativePostZygoteFork(JNIEnv*, jclass) {
   
  Runtime* runtime = Runtime::Current();
  if (runtime->IsZygote()) {
   
    runtime->PostZygoteFork();
  }
}

接着回到ZygotoInit,发现他调用了handleSystemServerProcess方法

class ZygotoInit{
   

    private static Runnable handleSystemServerProcess(ZygoteArguments parsedArgs) {
   
        // set umask to 0077 so new files and directories will default to owner-only permissions.
        Os.umask(S_IRWXG | S_IRWXO);

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

        final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH");
        if (systemServerClasspath != null) {
   
            if (performSystemServerDexOpt(systemServerClasspath)) {
   
                // Throw away the cached classloader. If we compiled here, the classloader would
                // not have had AoT-ed artifacts.
                // Note: This only works in a very special environment where selinux enforcement is
                // disabled, e.g., Mac builds.
                sCachedSystemServerClassLoader = null;
            }
            // Capturing profiles is only supported for debug or eng builds since selinux normally
            // prevents it.
            boolean profileSystemServer = SystemProperties.getBoolean(
                    "dalvik.vm.profilesystemserver", false);
            if (profileSystemServer && (Build.IS_USERDEBUG || Build.IS_ENG)) {
   
                try {
   
                    prepareSystemServerProfile(systemServerClasspath);
                } catch (Exception e) {
   
                    Log.wtf(TAG, "Failed to set up system server profile", e);
                }
            }
        }

        if (parsedArgs.mInvokeWith != null) {
   
            String[] args = parsedArgs.mRemainingArgs;
            // If we have a non-null system server class path, we'll have to duplicate the
            // existing arguments and append the classpath to it. ART will handle the classpath
            // correctly when we exec a new process.
            if (systemServerClasspath != null) {
   
                String[] amendedArgs = new String[args.length + 2];
                amendedArgs[0] = "-cp";
                amendedArgs[1] = systemServerClasspath;
                System.arraycopy(args, 0, amendedArgs, 2, args.length);
                args = amendedArgs;
            }

            WrapperInit.execApplication(parsedArgs.mInvokeWith,
                    parsedArgs.mNiceName, parsedArgs.mTargetSdkVersion,
                    VMRuntime.getCurrentInstructionSet(), null, args);

            throw new IllegalStateException("Unexpected return from WrapperInit.execApplication");
        } else {
   
            //字面意思 创建系统的classloader
            createSystemServerClassLoader();
            ClassLoader cl = sCachedSystemServerClassLoader;
            if (cl != null) {
   
                Thread.currentThread().setContextClassLoader(cl);
            }

            /*
             * Pass the remaining arguments to SystemServer.
             */
             // 进程初始化工作
            return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,
                    parsedArgs.mRemainingArgs, cl);
        }

        /* should never reach here */
    }
   public static final Runnable zygoteInit(int targetSdkVersion, String[] argv,
            ClassLoader classLoader) {
   
        if (RuntimeInit.DEBUG) {
   
            Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from zygote");
        }

        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit");
        RuntimeInit.redirectLogStreams();

        RuntimeInit.commonInit();
        ZygoteInit.nativeZygoteInit();
        return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
    }
    }


applicationInit方法进行初始化操作,

class RuntimeInit{
   

    protected static Runnable applicationInit(int targetSdkVersion, String[] argv,
            ClassLoader classLoader) {
   
        // If the application calls System.exit(), terminate the process
        // immediately without running any shutdown hooks.  It is not possible to
        // shutdown an Android application gracefully.  Among other things, the
        // Android runtime shutdown hooks close the Binder driver, which can cause
        // leftover running threads to crash before the process actually exits.
        nativeSetExitWithoutCleanup(true);

        // We want to be fairly aggressive about heap utilization, to avoid
        // holding on to a lot of memory that isn't needed.
        VMRuntime.getRuntime().setTargetHeapUtilization(0.75f);
        VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);

        final Arguments args = new Arguments(argv);

        // The end of of the RuntimeInit event (see #zygoteInit).
        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);

        // Remaining arguments are passed to the start class's static main
        return findStaticMain(args.startClass, args.startArgs, classLoader);
    }
    // 找到SystemServer入口
  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);
        }

        /*
         * This throw gets caught in ZygoteInit.main(), which responds
         * by invoking the exception's run() method. This arrangement
         * clears up all the stack frames that were required in setting
         * up the process.
         */
        return new MethodAndArgsCaller(m, argv);
    }
}

发现这里通过反射调用了SystemServer的main方法,发现他初始化了SystemServiceManager并且调用了startBootstrapServices();startCoreServices();startOtherServices();


class SystemServer{
   

  public static void main(String[] args) {
   
        new SystemServer().run();
    }
    
       private void run() {
   
        try {
   
            traceBeginAndSlog("InitBeforeStartServices");
            // If a device's clock is before 1970 (before 0), a lot of
            // APIs crash dealing with negative numbers, notably
            // java.io.File#setLastModified, so instead we fake it and
            // hope that time from cell towers or NTP fixes it shortly.
            if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) {
   
                Slog.w(TAG, "System clock is before 1970; setting to 1970.");
                SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);
            }

            //
            // Default the timezone property to GMT if not set.
            //
            String timezoneProperty =  SystemProperties.get("persist.sys.timezone");
            if (timezoneProperty == null || timezoneProperty.isEmpty()) {
   
                Slog.w(TAG, "Timezone not set; setting to GMT.");
                SystemProperties.set("persist.sys.timezone", "GMT");
            }

            // If the system has "persist.sys.language" and friends set, replace them with
            // "persist.sys.locale". Note that the default locale at this point is calculated
            // using the "-Duser.locale" command line flag. That flag is usually populated by
            // AndroidRuntime using the same set of system properties, but only the system_server
            // and system apps are allowed to set them.
            //
            // NOTE: Most changes made here will need an equivalent change to
            // core/jni/AndroidRuntime.cpp
            if (!SystemProperties.get("pers
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值