在Android系统中,有一群很厉害的“家伙”,如果把Android系统比喻成一个大帮派,那么这群“家伙”的地位就像那各个分堂的堂主一样,所有的应用就像是各个小马哥,他们要做什么事情,都要堂主审批,审批过了才能提交总部处理。
 
接下来我会牵扯出几个常用的堂主,并且简单介绍下他们的创建过程和对应的功能
 
ActivityManager是Android系统服务ActivityManagerService提供出来供应用调用的API,负责四大组件的支持
WindowManager是Android系统服务WindowManagerService提供出来供应用调用的的API,负责窗口管理
PackageManager是Android系统服务PackageManagerService提供出来供应用调用的的API,负责应用的包管理

这里,ActivityManager就是堂主的角色,而ActivityManagerService就是总部的角色

创建Manager

那么我们看一下这些Manager的创建过程

在Android的系统中存在这么一个类SystemServiceRegistry,这个类就是负责注册并存储,让我带大家了解一下服务的注册过程吧~

static {
    registerService(Context.ACTIVITY_SERVICE, ActivityManager.class,
            new CachedServiceFetcher<ActivityManager>() {
        @Override
        public ActivityManager createService(ContextImpl ctx) {
            return new ActivityManager(ctx.getOuterContext(), ctx.mMainThread.getHandler());
    }});
}
在静态代码块中,调用了静态方法registerService方法,传入Context下的key值和一个CachedServiceFetcher对象,我们看一下registerService函数

private static <T> void registerService(String serviceName, Class<T> serviceClass,
        ServiceFetcher<T> serviceFetcher) {
    SYSTEM_SERVICE_NAMES.put(serviceClass, serviceName);
    SYSTEM_SERVICE_FETCHERS.put(serviceName, serviceFetcher);
}
我们可以看到是把传进来的参数仅仅就是存入了Map集合中,这些Manager的真正创建其实是在调用context.getSystemService的时候。接下来我们来看一下获取Manager
 
获取Manager
 

当我们需要获取Manager服务的时候,我们通常会这样写

ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);

那么我们就从这个开始跟起,看一下Context下的getSystemService函数,Context的实现类为ContextImpl,所以我们直接看ContextImpl的getSystemService就好了

@Override
public Object getSystemService(String name) {
    return SystemServiceRegistry.getSystemService(this, name);
}
我们可以看到,是调用了SystemServiceRegistry的getSystemService方法
public static Object getSystemService(ContextImpl ctx, String name) {
    ServiceFetcher<?> fetcher = SYSTEM_SERVICE_FETCHERS.get(name);
    return fetcher != null ? fetcher.getService(ctx) : null;
}

这里通过传入的key值,从Map集合中在取出CachedServiceFetcher对象,并调用getService方法,我们看一下getService

@Override
@SuppressWarnings("unchecked")
public final T getService(ContextImpl ctx) {
    final Object[] cache = ctx.mServiceCache;
    synchronized (cache) {
        // Fetch or create the service.
        Object service = cache[mCacheIndex];
        if (service == null) {
            try {
                service = createService(ctx);
                cache[mCacheIndex] = service;
            } catch (ServiceNotFoundException e) {
                onServiceNotFound(e);
            }
        }
        return (T)service;
    }
}
这里是先获取了Manager的缓存数组mServiceCache,然后先从数组中获取,如果为空在创建,负责直接返回数组内历史创建的实例出来
这块的createService就是先前CachedServiceFetcher对象下的createService函数,就是registerService传入的CachedServiceFetcher对象下的createService函数
 
这些Manager其实在系统开机的时候,就做好了注册工作,就等调用的时候createService就好了。

Android 系统服务的获取与创建的更多相关文章

  1. Android系统服务-WindowManager

      WindowManager是Android中一个重要的服务 (Service ).WindowManager Service 是全局的,是唯一的.它将用户的操作,翻译成为指令,发送给呈现在界面上的 ...

  2. Android系统服务详解-android学习之旅(95)

    本文是看完android框架揭秘第六章后的总结 android系统服务提供最基本的,最稳定的核心功能,如设备控制,信息通知,通知设定,以及消息显示等,存在于Android Framework与Andr ...

  3. 新建android系统服务

    一.Android系统服务 Android提供了很多系统服务:如ActivityManger,PowerManger,WindowManger,WifiManger等等. 这些服务都是系统启动开始就一 ...

  4. Android开发程序获取GPS信息步骤

    1.获取LOCATION_SERVICE系统服务.2.创建Criteria对象,调用该对象的set方法设置查询条件.3.调用LocationManager.getBestProvider(Criter ...

  5. Android开发之获取xml文件的输入流对象

    介绍两种Android开发中获取xml文件的输入流对象 第一种:通过assets目录获取 1.首先是在Project下app/src/main目录下创建一个assets文件夹,将需要获取的xml文件放 ...

  6. Android 上SuperUser获取ROOT权限原理解析

    Android 上SuperUser获取ROOT权限原理解析 一. 概述 本文介绍了android中获取root权限的方法以及原理,让大家对android 玩家中常说的“越狱”有一个更深层次的认识. ...

  7. (android 地图实战开发)2 创建MapActivity,根据设备当前位置,显示地图

    (android 地图实战开发)2 创建MapActivity,根据设备当前位置,显示地图 http://www.cnblogs.com/macroxu-1982/archive/2011/09/13 ...

  8. xamarin.android之 Android 4.4+ 获取图片真实路径

    Android 4.4以下 选择图片是可以获取到图片路径的.高于Android 4.4获取图片路径只是获取到一个图片编号. 所以需要针对Android版本进行路径解析: #region 高于 v4.4 ...

  9. android 通过socket获取IP

    如题<android 通过socket获取IP>: socket.getInetAddress().getHostAddress();

随机推荐

  1. 基于 HTTP 请求拦截,快速解决跨域和代理 Mock

    近几年,随着 Web 开发逐渐成熟,前后端分离的架构设计越来越被众多开发者认可,使得前端和后端可以专注各自的职能,降低沟通成本,提高开发效率. 在前后端分离的开发模式下,前端和后端工程师得以并行工作. ...

  2. Java面试前需要了解的东西

    一.前言 只有光头才能变强 回顾前面: 广州三本找Java实习经历 上一篇写了自己面试的经历和一些在面试的时候遇到的题目(笔试题和面试题). 我在面试前针对Java基础也花了不少的时间,期间也将自己写 ...

  3. Linux 系统调用过程详细分析

    内核版本:Linux-4.19 操作系统通过系统调用为运行于其上的进程提供服务. 那么,在应用程序内,调用一个系统调用的流程是怎样的呢? 我们以一个假设的系统调用 xyz() 为例,介绍一次系统调用的 ...

  4. 第13章 Base64 URL编码 - IdentityModel 中文文档(v1.0.0)

    JWT令牌使用Base64 URL编码进行序列化. IdentityModel包括Base64Url帮助编码/解码的类: var text = "hello"; var b64ur ...

  5. d3实现家族树

      1.  jQuery和CSS3支持移动手机的DOM元素移动和缩放插件:panzoom   2.拖动:jqueryUI-Draggable.touchpunch   3.图表:echart.heig ...

  6. .net mvc + layui做图片上传(一)

    图片上传和展示是互联网应用中比较常见的一个功能,最近做的一个门户网站项目就有多个需要上传图片的功能模块.关于这部分内容,本来功能不复杂,但后面做起来却还是出现了一些波折.因为缺乏经验,对几种图片上传的 ...

  7. openlayers4 入门开发系列之地图空间查询篇(附源码下载)

    前言 openlayers4 官网的 api 文档介绍地址 openlayers4 api,里面详细的介绍 openlayers4 各个类的介绍,还有就是在线例子:openlayers4 官网在线例子 ...

  8. 章节九、5-IE Driver

    一.下载IE浏览器驱动,然后解压到存放谷歌和火狐驱动的相同路径中(请观看前面的章节) 下载地址一:http://selenium-release.storage.googleapis.com/inde ...

  9. SQL Server 创建跨库查詢、修改、增加、删除

    一.通过SQL语句访问远程数据库   --OPENROWSET函数 使用OPENROWSET()是个不错的选择,也可以用做跨库查询包括增.删.改.查 下面就来介绍一下OPENROWSET函数的运用 包 ...

  10. Iterm2/Mac自带终端工具快速进入你想进入的虚拟机教程

    一.首先我们在终端本地要写一个登录的脚本,eg: 当然首先要touch login.sh 啦,下面就是脚本文件,比较low,大神勿喷,会更炫酷写法的小伙伴可以自己参考这个思路写,不会的直接复制就好啦 ...