LocalServices和SystemService等简介

Android  源码分析  2023年8月19日 am8:08发布1年前 (2023)更新 城堡大人
114 0 0

前言

在上次简单介绍SystemServer(《SystenServer的启动之一》)时,里面涉及几个比较重要的类SystemServiceManagerSystemServiceLocalServices,因此今天就单独介绍一下。

正文

涉及文件

frameworks\base\services\java\com\android\server\SystemServer.java
frameworks\base\services\core\java\com\android\server\SystemService.java
frameworks\base\services\core\java\com\android\server\SystemServiceManager.java
frameworks\base\core\java\com\android\server\LocalServices.java
frameworks\base\services\core\java\com\android\server\lights\LightsService.java

SystemService.java

虽然名字带有Service,并不是真正的Service,只是一个抽象类,定义了些[系统服务]共同的方法和属性。

这个主要是让系[统服务]]继承这个类。

比如

//Installer.java
public class Installer extends SystemService {
}
//PowerManagerService.java
public final class PowerManagerService extends SystemService
        implements Watchdog.Monitor {
}
//LightsService.java
public class LightsService extends SystemService {
}

SystemServiceManager.java

mSystemServiceManager = new SystemServiceManager(mSystemContext);

这个mSystemServiceManager在SystemServer中很常见,主要功能:

  1. 启动[系统服务]

  2. 通知[系统服务]更新Boot Phase

  3. 通知[系统服务]切换用户

SystemServiceManager中存在mServices列表,用于存储启动过的[系统服务]。

private final ArrayList<SystemService> mServices = new ArrayList<SystemService>();
启动[系统服务]

这块之前在《SystenServer的启动之一》介绍过。

startService()
public SystemService startService(String className) {
    final Class<SystemService> serviceClass;
    try {
        //返回className类对象,如果无法加载就会异常。
        serviceClass = (Class<SystemService>)Class.forName(className);
    } catch (ClassNotFoundException ex) {
        throw new RuntimeException("Failed to create service " + className
                + ": service class not found, usually indicates that the caller should "
                + "have called PackageManager.hasSystemFeature() to check whether the "
                + "feature is available on this device before trying to start the "
                + "services that implement it", ex);
    }
    return startService(serviceClass);
}

接着的startService()主要作用:

  1. 判断serviceClass是否继承SystemService

  2. 获取构造函数初始化Service

  3. 启动服务的startService()

@SuppressWarnings("unchecked")
public <T extends SystemService> T startService(Class<T> serviceClass) {
    try {
        final String name = serviceClass.getName();
        //判断serviceClass继承于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对象初始化
         service = constructor.newInstance(mContext);
        } catch (InstantiationException ex) {
            throw new RuntimeException("Failed to create service " + name
                    + ": service could not be instantiated", ex);
        }
        startService(service);
        return service;//返回创建的服务对象
    } finally {
        Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
    }
}
  1. 添加创建的service到mServices列表中,方便后续获取和查询

  2. 调用服务中的onStart()

public void startService(@NonNull final SystemService service) {
    //添加到服务列表,后面可以通过getService获取服务。
    mServices.add(service);
    try {
        //调用服务中的onStart()
        service.onStart();
    } catch (RuntimeException ex) {
        throw new RuntimeException("Failed to start service " + service.getClass().getName()
                + ": onStart threw an exception", ex);
    }
}

哈哈,从上面看,[系统服务]也就是模拟服务启动而已。完全可以看做创建了一个类对象并执行了onStart()。

更新Phase状态
public void startBootPhase(final int phase) {
    //mCurrentPhase默认-1
    if (phase <= mCurrentPhase) {
        throw new IllegalArgumentException("Next phase must be larger than previous");
    }
    //更新mCurrentPhase
    mCurrentPhase = phase;
    try {
        final int serviceLen = mServices.size();
        //有新phase状态,通知所有启动了的[系统服务]
        for (int i = 0; i < serviceLen; i++) {
            final SystemService service = mServices.get(i);
            long time = SystemClock.elapsedRealtime();
            try {
                service.onBootPhase(mCurrentPhase);
            } catch (Exception ex) {
                throw new RuntimeException("Failed to boot service "
                        + service.getClass().getName()
                        + ": onBootPhase threw an exception during phase "
                        + mCurrentPhase, ex);
            }
        }
    } finally {
    }
}
切换用户

至于切换用户,这里涉及如下几个方法

  1. startUser()

  2. unlockUser()

  3. switchUser()

  4. stopUser()

  5. cleanupUser()

Android是支持多用户的,也就是每个用户的配置信息不一样,因此每次变化都需要通知所有[系统服务]进行切换对用的配置。

LocalServices.java

LocalServices类也很简单,也就是用map存储[服务],然后提供添加,查询和删除功能。

存在的不一定是服务哈!

public final class LocalServices {
    private LocalServices() {}
    //用键值对存储服务
    private static final ArrayMap<Class<?>, Object> sLocalServiceObjects =
            new ArrayMap<Class<?>, Object>();
    //通过key进行查询服务
    @SuppressWarnings("unchecked")
    public static <T> T getService(Class<T> type) {
        synchronized (sLocalServiceObjects) {
            return (T) sLocalServiceObjects.get(type);
        }
    }
    //通过key添加服务
    public static <T> void addService(Class<T> type, T service) {
        synchronized (sLocalServiceObjects) {
            if (sLocalServiceObjects.containsKey(type)) {
                throw new IllegalStateException("Overriding service registration");
            }
            sLocalServiceObjects.put(type, service);
        }
    }
    //通过key进行移除服务
    @VisibleForTesting
    public static <T> void removeServiceForTest(Class<T> type) {
        synchronized (sLocalServiceObjects) {
            sLocalServiceObjects.remove(type);
        }
    }
}

这个也在代码中很常用

SystemServer.run()
# 存储mSystemServiceManager
LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
LightsService.onStart()
@Override
public void onStart() {
    publishLocalService(LightsManager.class, mService);
}
protected final <T> void publishLocalService(Class<T> type, T service) {
    LocalServices.addService(type, service);
}

这里添加的是LightsManager对象。

参考文章

  1. SystenServer的启动之一

 历史上的今天

  1. 2021: Android ImageView 的scaleType属性简介(0条评论)
  2. 2020: Android动画之RotateAnimation(0条评论)
  3. 2019: 周国平:爱的距离(0条评论)
版权声明 1、 本站名称: 笔友城堡
2、 本站网址: https://www.biumall.com/
3、 本站部分文章来源于网络,仅供学习与参考,如有侵权,请留言

暂无评论

暂无评论...

随机推荐

《MySQL基础教程》笔记4

前言本文主要是select语句的使用学习一下MySQL,一直没有系统的学习一下。最近有空,看了《MySQL基础教程-西泽梦路》,简单的做一下笔记。记录于此,方便自己回忆。MySQL中对大小写没有区分,我这里习惯性用小些。正文我这以Window版的phpstudy软件验证。需要进入...

Activity的启动模式分析

以下是主要的测试代码package com.hi.hello;import android.app.Activity;import android.content.Intent;import android.os.Bundle;import android.util.Log;impor...

龙应台:我为什么要求你读书

那天我问你,“你将来想做什么”,我注意到,你很不屑于回答我这个问题,所以跟我胡诌一通。是因为你们这个时代的人,对未来太自信,所以不屑与像我这一代人年轻时一样,讲究勤勤恳恳、如履薄冰,还是其实你们对于未来太没信心,所以假装出一种嘲讽和狂妄的姿态,来闪避我的追问?我几乎要相信,你是在假装潇洒了。今天的...

Android修改原生电话铃声

前言简单记录一下,修改Android原生默认的铃声。推荐看参考文章,这里只是个人随笔记录。正文隐藏内容!付费阅读后才能查看!¥1 ¥3多个隐藏块只需支付一次付费阅读参考文章《Android 设置铃声》《Android 设置来电铃声、通知铃声、闹钟铃声中的坑》

[摘]音视频学习系列第(一)篇---基础概念

shui知道最在学习这个,这个博主总结得不错,因此摘抄于此,以方便自己查阅。可访问改博主sofarsogoo_932d的一系列文章《音视频学习系列》,感谢他的分享。什么是音/视频音频声音的集合视频图片的集合,当一段连续的图片不断的出现在人眼前(至少要求1秒24帧,即一秒内连续出...

林清玄:阳光的味道

尘世的喧嚣,让我们遗忘了阳光的味道,味道是一样的纯净着,一样的微小,一丝丝,入心、入肺。甘甜、芬芳、怡人。阳光的味道很干净和唯美,像川端的小说,透明、简洁、历炼。行走在世上,许多靶子等待我们绷紧的箭矢去努力的命中。心里装满太多的世故与繁忧,幸福的位置,也就变得小了,或者卑微到忽略不计。很向往年关过...