美文网首页
Android Framework 之 SystemServer

Android Framework 之 SystemServer

作者: 你怕是很皮哦 | 来源:发表于2021-03-17 18:45 被阅读0次

    阅读须知

    本文源码基于 Android 10

    Questions

    1. 如何处理系统服务启动的依赖关系?
    2. 如何发布系统服务,让其对其他应用或服务可见?

    SystemServer

    Zygote 一文中简单的提到了 Zygote 启动后会去启动 SystemServer。本文将从源码的角度对 SystemServer 做一个详细的分析。

    本文的大致流程如下图所示。

    image.png

    启动 SystemServer

    首先看看 SystemServer 的启动。这里主要做了如下事情:

    1. Zygote 设置 SigChld 信号处理;
    2. 通过 fork() 孵化出 system_server
    image.png

    还记得 ZygoteInit.main() 里启动 SystemServer 的代码吗?

    // frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
    
    public static void main(String argv[]) {
        Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);
        if (r != null) {
            r.run();
            return;
        }
    }
    
    private static Runnable forkSystemServer(String abiList, String socketName,
            ZygoteServer zygoteServer) {
        // 参数组装
        String args[] = {
            // ...
            "com.android.server.SystemServer",
        };
        ZygoteArguments parsedArgs = null;
        parsedArgs = new ZygoteArguments(args);
        // 启动 system_server 进程
        pid = Zygote.forkSystemServer(
                parsedArgs.mUid, parsedArgs.mGid,
                parsedArgs.mGids,
                parsedArgs.mRuntimeFlags,
                null,
                parsedArgs.mPermittedCapabilities,
                parsedArgs.mEffectiveCapabilities);
    }
    

    注意这里启动 SystemServer 传递的参数 com.android.server.SystemServer,后面会用到。这里的调用链如下图所示。

    image.png

    设置 SigChld 信号处理

    ForkCommon() 中首先会给 Zygote 设置 SigChld 信号处理。

    // frameworks/base/core/jni/com_android_internal_os_Zygote.cpp
    
    static pid_t ForkCommon(JNIEnv* env, bool is_system_server,
                            const std::vector<int>& fds_to_close,
                            const std::vector<int>& fds_to_ignore) {
      // 设置 SigChld 信号处理
      SetSignalHandlers();
    }
    
    static void SetSignalHandlers() {
      struct sigaction sig_chld = {};
      // 当收到 SigChld 信号的时候调用 SigChldHandler
      sig_chld.sa_handler = SigChldHandler;
    }
    
    static void SigChldHandler(int /*signal_number*/) {
      while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
        // 当 system_server 进程挂掉了,则把 zygote 干掉,让 init 去重启 zygote
        if (pid == gSystemServerPid) {
          kill(getpid(), SIGKILL);
        }
      }
    }
    

    system_server 挂掉时 Zygote 会收到 SigChld 信号,然后 Zygotekill 自身,让 init 来重启 Zygote

    这里的 gSystemServerPidsystem_serverpid,它是在 ForkCommon() 调用后赋值的。

    // frameworks/base/core/jni/com_android_internal_os_Zygote.cpp
    
    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) {  
      // 这里调用的 FormCommon()
      pid_t pid = ForkCommon(env, true,
                             fds_to_close,
                             fds_to_ignore);
      if (pid == 0) {
          // pid == 0 表示在 system_server 进程
      } else if (pid > 0) {
          // pid > 0 表示在父进程,这里 gSystemServerPid 赋值为 system_server 的进程id
          gSystemServerPid = pid;
      }
      return pid;
    }
    

    孵化 system_server 进程

    设置完 SigChld 信号处理后,就通过 fork() 孵化 system_server 进程。

    // frameworks/base/core/jni/com_android_internal_os_Zygote.cpp
    
    static pid_t ForkCommon(JNIEnv* env, bool is_system_server,
                            const std::vector<int>& fds_to_close,
                            const std::vector<int>& fds_to_ignore) {
      // fork system_server 进程
      pid_t pid = fork();
    }
    

    关于 fork(),这里简单说明一下,它被调用一次,会返回两次,有 3 种不同的返回值:

    • 在父进程中,fork() 返回子进程的 pid
    • 在子进程中,fork() 返回 0;
    • fork 子进程报错时返回负值。

    因为当进程调用 fork() 后,控制转移到内核中的 fork() 代码,内核会做 4 件事情:

    1. 分配新的内存块和内核数据结构给子进程;
    2. 将父进程部分数据结构内容拷贝至子进程;
    3. 添加子进程到系统进程列表当中;
    4. fork() 返回,开始调度器调度。

    所以当程序执行 pid = fork() 时,由于在复制时子进程复制了父进程的堆栈段或相应的变量与数据结构,所以两个进程都停留在 fork() 中,等待返回。

    因此 fork() 会返回两次,一次是在父进程中返回,另一次是在子进程中返回,这两次的返回值是不一样的。

    准备工作

    forksystem_server 后,会做一些初始化工作。主要包括:

    1. 一些常规的初始化,然后启动 binder 线程;
    2. 查找并调用 SystemServer.main()
    image.png

    回到 ZygoteInit 接着 forkSystemServer() 往下看。

    // frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
    
    private static Runnable forkSystemServer(String abiList, String socketName,
                ZygoteServer zygoteServer) {
        // fork system_server
        pid = Zygote.forkSystemServer(
                        parsedArgs.mUid, parsedArgs.mGid,
                        parsedArgs.mGids,
                        parsedArgs.mRuntimeFlags,
                        null,
                        parsedArgs.mPermittedCapabilities,
                        parsedArgs.mEffectiveCapabilities);
        // pid == 0 表示在 system_server 进程
        if (pid == 0) {
            // 调用 handleSystemServerProcess 做一些初始化工作
            return handleSystemServerProcess(parsedArgs);
        }
    }
    

    这里 pid == 0 即在 system_server 进程,其调用链如下图红框所示。

    image.png

    启动 binder 线程

    zygoteInit() 中会先做一些常规的初始化操作,然后开启 binder 线程。

    // frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
    
    public static final Runnable zygoteInit(int targetSdkVersion, String[] argv,
            ClassLoader classLoader) {
        ZygoteInit.nativeZygoteInit();
    }
    
    // frameworks/base/core/jni/AndroidRuntime.cpp
    
    static void com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env, jobject clazz)
    {
        // gCurRuntime 即 AppRuntime
        gCurRuntime->onZygoteInit();
    }
    
    // frameworks/base/cmds/app_process/app_main.cpp
    
    virtual void onZygoteInit()
    {
        sp<ProcessState> proc = ProcessState::self();
        // 开启 binder 线程
        proc->startThreadPool();
    }
    

    这里的 gCurRuntime 就是 AppRuntime,它是在 Zygote 的入口函数 app_main.main() 被赋值的。

    // frameworks/base/cmds/app_process/app_main.cpp
    
    int main(int argc, char* const argv[])
    {
        // AppRuntime 继承了 AndroidRuntime
        AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));
    }
    
    // frameworks/base/core/jni/AndroidRuntime.cpp
    
    AndroidRuntime::AndroidRuntime(char* argBlockStart, const size_t argBlockLength) :
            mExitWithoutCleanup(false),
            mArgBlockStart(argBlockStart),
            mArgBlockLength(argBlockLength)
    {
        // 在 AndroidRuntime 构造器里面会将 gCurRuntime 赋值为 AppRuntime
        gCurRuntime = this;
    }
    

    查找并调用 SystemServer.main()

    启动 binder 线程后,紧接着会去查找并调用 com.android.server.SystemServer (前面提到过的参数)的 static main()

    // frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
    
    public static final Runnable zygoteInit(int targetSdkVersion, String[] argv,
            ClassLoader classLoader) {
        return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
    }
    
    // frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
    
    protected static Runnable applicationInit(int targetSdkVersion, String[] argv,
            ClassLoader classLoader) {
        return findStaticMain(args.startClass, args.startArgs, classLoader);
    }
    
    protected static Runnable findStaticMain(String className, String[] argv,
        ClassLoader classLoader) {
        Class<?> cl;
    
        try {
            cl = Class.forName(className, true, classLoader);
        } catch (ClassNotFoundException ex) {
        }
    
        // 反射查找 main()
        Method m;
        try {
            m = cl.getMethod("main", new Class[] { String[].class });
        } catch (NoSuchMethodException ex) {
        } catch (SecurityException ex) {
        }
    
        // 判断是不是 public static
        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);
    }
    
    static class MethodAndArgsCaller implements Runnable {
    
        public void run() {
            try {
                // 调用 main()
                mMethod.invoke(null, new Object[] { mArgs });
            } catch (IllegalAccessException ex) {
            } catch (InvocationTargetException ex) {
            }
        }
    }
    

    SystemServer工作流程

    进入 SystemServer.main() 后就开始 SystemServer 的工作流程了。这里主要会做如下事情:

    1. 初始化主线程 Looper
    2. 加载 android_servers.so 库;
    3. 初始化系统上下文;
    4. 创建系统服务管理者 SystemServiceManager
    5. 分批次分阶段性的启动服务;
    6. 进入 loop() 循环等待和处理请求。
    image.png

    SystemServer.main() 简单粗暴,直接创建 SystemServer,然后调用其 run()

    // frameworks/base/services/java/com/android/server/SystemServer.java
    
    public static void main(String[] args) {
        new SystemServer().run();
    }
    

    初始化主线程 Looper

    首先会初始化主线程 Looper

    // frameworks/base/services/java/com/android/server/SystemServer.java
    
    private void run() {
        Looper.prepareMainLooper();
    }
    

    加载 android_servers.so

    接着加载 android_servers.so 库,该库包含的源码位于 frameworks/base/services/core/jni 下。

    // frameworks/base/services/java/com/android/server/SystemServer.java
    
    private void run() {
        System.loadLibrary("android_servers");
    }
    

    初始化系统上下文

    接着会初始化系统上下文。

    // frameworks/base/services/java/com/android/server/SystemServer.java
    
    private void run() {
        createSystemContext();
    }
    

    其调用链如下图所示,它和应用进程类似,也会创建 ActivityThread,调用其 attach(),创建 Application 等。

    image.png

    构建包名为 android 的 LoadedApk

    这里主要看下 ContextImpl.createSystemContext()

    // frameworks/base/core/java/android/app/ContextImpl.java
    
    static ContextImpl createSystemContext(ActivityThread mainThread) {
        // 构建包名为 android 的 LoadedApk
        LoadedApk packageInfo = new LoadedApk(mainThread);
        // 构建 ContextImpl
        ContextImpl context = new ContextImpl(null, mainThread, packageInfo, null, null, null, 0,
                null, null);
        return context;
    }
    
    // frameworks/base/core/java/android/app/LoadedApk.java
    
    LoadedApk(ActivityThread activityThread) {
        mActivityThread = activityThread;
        mApplicationInfo = new ApplicationInfo();
        // 包名为 android
        mApplicationInfo.packageName = "android";
        mPackageName = "android";
    }
    

    可以看到这里构建了一个包名为 androidLoadedApk

    构建 Resources

    接着会创建 ResourcesImpl

    // frameworks/base/core/java/android/app/LoadedApk.java
    
    LoadedApk(ActivityThread activityThread) {
        mResources = Resources.getSystem();
    }
    
    // frameworks/base/core/java/android/content/res/Resources.java
    
    private Resources() {
        // 创建 ResourceImpl,并调用 AssetManager.getSystem()
        mResourcesImpl = new ResourcesImpl(AssetManager.getSystem(), metrics, config,
                new DisplayAdjustments());
    }
    

    加载 framework-res.apk

    在创建 ResourceImpl 时调用了 AssetManager.getSystem(),这里会加载 framework-res.apk,并创建 AssetManager

    // frameworks/base/core/java/android/content/res/AssetManager.java
    
    // frameowrk-res.apk 路径
    private static final String FRAMEWORK_APK_PATH = "/system/framework/framework-res.apk";
    
    static AssetManager sSystem = null;
    
    public static AssetManager getSystem() {
        synchronized (sSync) {
            // 这里会加载 framework-res.apk
            createSystemAssetsInZygoteLocked();
            return sSystem;
        }
    }
    
    private static void createSystemAssetsInZygoteLocked() {
        final ArrayList<ApkAssets> apkAssets = new ArrayList<>();
        // 加载 framework-res.apk
        apkAssets.add(ApkAssets.loadFromPath(FRAMEWORK_APK_PATH, true /*system*/));
        sSystemApkAssets = apkAssets.toArray(new ApkAssets[apkAssets.size()]);
        // 创建 AssetManager
        sSystem = new AssetManager(true /*sentinel*/);
        // 设置 apk 资源
        sSystem.setApkAssets(sSystemApkAssets, false /*invalidateCaches*/);
    }
    

    创建 SystemServiceManager

    接着会创建 SystemServiceManager

    // frameworks/base/services/java/com/android/server/SystemServer.java
    
    private void run() {
        mSystemServiceManager = new SystemServiceManager(mSystemContext);
    }
    

    SystemServiceManager

    SystemServiceManager 是用来管理系统服务(继承自 SystemService 的类)的创建、启动和其他生命周期事件。

    关于 SystemServiceManager 主要关注其两个方法 startService()startBootPhase()

    startService()

    startService() 是用来创建系统服务,并将系统服务添加到 mServices 集合中进行统一的管理,最后调用系统服务的 onStart()

    // frameworks/base/services/java/com/android/server/SystemService.java
    
    // 对 SystemService 进行统一的管理
    private final ArrayList<SystemService> mServices = new ArrayList<SystemService>();
        
    public SystemService startService(String className) {
        final Class<SystemService> serviceClass;
        try {
            serviceClass = (Class<SystemService>)Class.forName(className);
        } catch (ClassNotFoundException ex) {
        }
        return startService(serviceClass);
    }
    
    public <T extends SystemService> T startService(Class<T> serviceClass) {
        final String name = serviceClass.getName();
        // 判断是否是继承自 SystemService
        if (!SystemService.class.isAssignableFrom(serviceClass)) {
            throw new RuntimeException("Failed to create " + name
                    + ": service must extend " + SystemService.class.getName());
        }
        // 反射创建
        final T service;
        try {
            Constructor<T> constructor = serviceClass.getConstructor(Context.class);
            service = constructor.newInstance(mContext);
        } catch (InstantiationException ex) {
        } catch (IllegalAccessException ex) {
        } catch (NoSuchMethodException ex) {
        } catch (InvocationTargetException ex) {
        }
    
        startService(service);
        return service;
    }
    
    public void startService(@NonNull final SystemService service) {
        // 注册服务
        mServices.add(service);
        // 调用其 onStart()
        service.onStart();
    }
    
    startBootPhase()

    Android 系统的系统服务是非常之多的,这些系统服务之间或多或少会存在一些依赖关系,如何去保证这些系统服务都能够正常有序的启动就成了一个问题。SystemServer 通过分批分阶段的方式来解决这个问题。

    当启动到达不同阶段的时候 SystemServer 会调用 startBootPhase(),这时 SystemServiceManager 就会通知已经添加到 mServices 中系统服务,这样系统服务只需要在不同的阶段做不同的事情即可。

    // frameworks/base/services/java/com/android/server/SystemService.java
    
    private int mCurrentPhase = -1;
    
    public void startBootPhase(final int phase) {
        // 保存当前所处阶段
        if (phase <= mCurrentPhase) {
            throw new IllegalArgumentException("Next phase must be larger than previous");
        }
        mCurrentPhase = phase;
    
        try {
            // 遍历 mServices 中的系统服务并调用其 onBootPhase()
            final int serviceLen = mServices.size();
            for (int i = 0; i < serviceLen; i++) {
                final SystemService service = mServices.get(i);
                try {
                    service.onBootPhase(mCurrentPhase);
                } catch (Exception ex) {
                }
            }
        } finally {
        }
    }
    

    SystemService

    SystemService 是系统服务的基类。

    关于 SystemService 主要关注其几个生命周期方法,onStart()publishBinderService()onBootPhase

    onStart()

    当服务启动后应调用此方法,一般会在里面发布服务。

    // frameworks/base/services/core/java/com/android/server/SystemService.java
    
    public abstract void onStart();
    
    publishBinderService()

    publishBinderService() 用于发布服务。

    系统服务通过此方法将自己的 IBinder 发布到 ServiceManager 中,这样其他应用或服务就可以访问到它。

    // frameworks/base/services/core/java/com/android/server/SystemService.java
    
    protected final void publishBinderService(String name, IBinder service) {
        publishBinderService(name, service, false);
    }
    
    protected final void publishBinderService(String name, IBinder service,
            boolean allowIsolated) {
        publishBinderService(name, service, allowIsolated, DUMP_FLAG_PRIORITY_DEFAULT);
    }
    
    protected final void publishBinderService(String name, IBinder service,
            boolean allowIsolated, int dumpPriority) {
        ServiceManager.addService(name, service, allowIsolated, dumpPriority);
    }
    
    onBootPhase()

    前面说了当到达不同阶段时,SystemServer 会通过 SystemServiceManagerstartBootPhase() 来通知系统服务,那系统服务可以通过重写 onBootPhase() 来接受不同阶段事件,并在所关心的阶段处理对应的事情。

    // frameworks/base/services/core/java/com/android/server/SystemService.java
    
    public abstract class SystemService {
    
        public static final int PHASE_WAIT_FOR_DEFAULT_DISPLAY = 100;
    
        public static final int PHASE_LOCK_SETTINGS_READY = 480;
        
        public static final int PHASE_SYSTEM_SERVICES_READY = 500;
    
        public static final int PHASE_DEVICE_SPECIFIC_SERVICES_READY = 520;
    
        public static final int PHASE_ACTIVITY_MANAGER_READY = 550;
    
        public static final int PHASE_THIRD_PARTY_APPS_CAN_START = 600;
        
        public static final int PHASE_BOOT_COMPLETED = 1000;
        
        public void onBootPhase(int phase) {}
    }
    

    启动服务

    创建完 SystemServiceManager 后,就开始启动服务。前面说过 SystemServer 通过分批分阶段的方式来启动服务,系统服务被分为引导服务、核心服务和其他服务三批进行启动,分别对应 startBootstrapServices()startCoreServices()startOtherServices()

    启动引导服务

    startBootstrapServices() 会启动引导服务,包括我们所熟知的 ActivityManagerServicePackageManagerService 等。

    // frameworks/base/services/java/com/android/server/SystemServer.java
    
    private void startBootstrapServices() {
        // 启动 ActivityManagerService
        ActivityTaskManagerService atm = mSystemServiceManager.startService(
                ActivityTaskManagerService.Lifecycle.class).getService();
        mActivityManagerService = ActivityManagerService.Lifecycle.startService(
                mSystemServiceManager, atm);
        mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
    
        mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class);
        // 通知 SystemServiceManager 到了 PHASE_WAIT_FOR_DEFAULT_DISPLAY 阶段
        mSystemServiceManager.startBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);
    
        // 启动 PackageManagerService
        try {
            mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
                    mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
        } finally {
        }
    
        mActivityManagerService.setSystemProcess();
    }
    

    关于 ActivityManagerService 后面有文章做详细的分析。

    启动核心服务

    startCoreServices() 会启动核心服务,包括 BatteryServiceGpuService 等等。

    // frameworks/base/services/java/com/android/server/SystemServer.java
    private void startCoreServices() {
        // BatterService
        mSystemServiceManager.startService(BatteryService.class);
        
        // GpuService
        mSystemServiceManager.startService(GpuService.class);
    }
    

    启动其他服务

    startOtherServices() 会分阶段启动其他服务,方法很长,感兴趣的自行去研究。

    // frameworks/base/services/java/com/android/server/SystemServer.java
    
    private void startOtherServices() {
        // VibratorService
        vibrator = new VibratorService(context);
        ServiceManager.addService("vibrator", vibrator);
    
        // AlarmManagerService
        mSystemServiceManager.startService(new AlarmManagerService(context));
    
        inputManager = new InputManagerService(context);
        // WindowManagerService
        wm = WindowManagerService.main(context, inputManager, !mFirstBoot, mOnlyCore,
                new PhoneWindowManager(), mActivityManagerService.mActivityTaskManager);
        ServiceManager.addService(Context.WINDOW_SERVICE, wm, /* allowIsolated= */ false,
                DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PROTO);
        // InputManagerService
        ServiceManager.addService(Context.INPUT_SERVICE, inputManager,
        mActivityManagerService.setWindowManager(wm);
    
        // AccessibilityManagerService
        try {
            mSystemServiceManager.startService(ACCESSIBILITY_MANAGER_SERVICE_CLASS);
        } catch (Throwable e) {
            reportWtf("starting Accessibility Manager", e);
        }
    
        // JobSchedulerService
        mSystemServiceManager.startService(JobSchedulerService.class);
    
        // 通知 SystemServiceManager 到达 PHASE_LOCK_SETTINGS_READY 阶段
        mSystemServiceManager.startBootPhase(SystemService.PHASE_LOCK_SETTINGS_READY);
        // 通知 SystemServiceManager 到达 PHASE_SYSTEM_SERVICES_READY 阶段
        mSystemServiceManager.startBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY);
    
        final Configuration config = wm.computeNewConfiguration(DEFAULT_DISPLAY);
        DisplayMetrics metrics = new DisplayMetrics();
        WindowManager w = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        w.getDefaultDisplay().getMetrics(metrics);
        context.getResources().updateConfiguration(config, metrics);
    
        mPackageManagerService.systemReady();
    
        // 通知 SystemServiceManager 到达 PHASE_DEVICE_SPECIFIC_SERVICES_READY 阶段
        mSystemServiceManager.startBootPhase(SystemService.PHASE_DEVICE_SPECIFIC_SERVICES_READY);
    
        // 调用 AMS 的 systemReady()
        mActivityManagerService.systemReady(() -> {
            // 通知 SystemServiceManager 到达 PHASE_ACTIVITY_MANAGER_READY 阶段
            mSystemServiceManager.startBootPhase(
                        SystemService.PHASE_ACTIVITY_MANAGER_READY);
        }
    
        // 通知 SystemServiceManager 到达 PHASE_THIRD_PARTY_APPS_CAN_START 阶段
        mSystemServiceManager.startBootPhase(
            SystemService.PHASE_THIRD_PARTY_APPS_CAN_START);
    }
    

    进入 loop() 循环

    最后会调用主线程 Looperloop() 进入循环等待处理请求。

    // frameworks/base/services/java/com/android/server/SystemServer.java
    
    private void run() {
        Looper.loop();
    }
    

    Answers

    至此 SystemServer 就分析完了,接下来回过头看看前面的问题。

    如何处理系统服务启动的依赖关系?

    SystemServer 通过分批分阶段的方式来启动 ServiceManager
    分批是指将系统服务分为三批:

    1. 启动引导服务,startBootstrapServices()
    2. 启动核心服务,startCoreServices()
    3. 启动其他服务,startOtherServices()

    分阶段是 SystemServer 在不同的阶段会通过 startBootPhase() 通知 SystemServiceManager,进而通过 onBootPhase() 通知系统服务。

    如何发布系统服务,让其对其他应用或服务可见?

    发布服务最终是通过 ServiceManageraddService()

    继承自 SystemService 的系统服务可以在 onStart() 中通过 publishBinderService() 发布服务,其底层还是调用的 ServiceManageraddService()

    相关文章

      网友评论

          本文标题:Android Framework 之 SystemServer

          本文链接:https://www.haomeiwen.com/subject/ddkxcltx.html