往Android系统中添加服务的方法教程

前言

最近因为公司的平台要从Android 4.4.4 转战 Android 6.0, 带来的问题是之前我们在系统中添加了一些服务, 于是要将一些系统级的服务迁移过去,以及一些Framework 的自定义包.

碰巧在Gerrit上看到了添加系统服务这一块的patch.正好做个总结.虽然我不是Framework工程师, 但是了解Android系统还是很有好处的.

如何获取系统服务

我们获取系统服务都是在context中,getSystemService获取到的. 那么我们看一下getSystemService发生了哪些些事情.

getSystemService的实现是ContextImpl,我们去看一下ContextImpl的源码就知道了.

Android 4.4.4 (KitKat)

这里是Android4.4.4的源码, 6.0的源码过会儿看.

//这是我们获取服务的路口 @Override public Object getSystemService(String name) { //可以看到我们是从一个HashMap中拿的服务. ServiceFetcher fetcher = SYSTEM_SERVICE_MAP.get(name); return fetcher == null ? null : fetcher.getService(this); } private static final HashMap<String, ServiceFetcher> SYSTEM_SERVICE_MAP = new HashMap<String, ServiceFetcher>(); //这是注册服务的方法,请注意是静态方法 private static void registerService(String serviceName, ServiceFetcher fetcher) { if (!(fetcher instanceof StaticServiceFetcher)) { fetcher.mContextCacheIndex = sNextPerContextServiceCacheIndex++; } SYSTEM_SERVICE_MAP.put(serviceName, fetcher); }

我们还在ContextImpl中看到很多静态代码块.全是在注册服务,并且全是我们常用的系统服务.

static { registerService(ACCESSIBILITY_SERVICE, new ServiceFetcher() { public Object getService(ContextImpl ctx) { return AccessibilityManager.getInstance(ctx); }}); registerService(CAPTIONING_SERVICE, new ServiceFetcher() { public Object getService(ContextImpl ctx) { return new CaptioningManager(ctx); }}); .... }

这么看来,这不就是我们注册服务的地方么?

So. 我们找到了注册系统服务的地方, 这里我们只需要把我们自己想注册的服务添加进去,完成new ServiceFetcher() 的抽象方法就行啦. 这样我们以后再getSystemService,传入注册时的名称,就可以获取到我们的服务对象了了.当然,这是4.4的方法.

Android 6.0 (Marshmallow)

我们来看一下ContextImpl的代码

@Override public Object getSystemService(String name) { return SystemServiceRegistry.getSystemService(this, name); }

我们发现,与 KitKat 大大不同, Marshmallow这里是从一个叫做SystemServiceRegistry的类去获取的.

好了,那我们去看它的源码,原来还是和以前一样的套路,不过是单独封装了一个类来管理这些注册的服务. 这么设计的确好,代码上的耦合度看上去小多了,且不会使得ContextImpl这个类越来月臃肿.

final class SystemServiceRegistry { private final static String TAG = "SystemServiceRegistry"; // Service registry information. // This information is never changed once static initialization has completed. private static final HashMap<Class<?>, String> SYSTEM_SERVICE_NAMES = new HashMap<Class<?>, String>(); private static final HashMap<String, ServiceFetcher<?>> SYSTEM_SERVICE_FETCHERS = new HashMap<String, ServiceFetcher<?>>(); private static int sServiceCacheSize; // Not instantiable. private SystemServiceRegistry() { } static { registerService(Context.ACCESSIBILITY_SERVICE, AccessibilityManager.class, new CachedServiceFetcher<AccessibilityManager>() { @Override public AccessibilityManager createService(ContextImpl ctx) { return AccessibilityManager.getInstance(ctx); }}); registerService(Context.CAPTIONING_SERVICE, CaptioningManager.class, new CachedServiceFetcher<CaptioningManager>() { @Override public CaptioningManager createService(ContextImpl ctx) { return new CaptioningManager(ctx); }}); ....

So.我们 Marshmallow 的系统服务应该在SystemServiceRegistry类中添加.一样的方式. 之后我们再getSystemService,传入注册时的名称,就可以获取到我们的服务对象了了.

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对脚本之家的支持。

时间: 2024-11-08 21:23:46

往Android系统中添加服务的方法教程的相关文章

详细分析Android系统中定位服务的架构和实现

对于 Android 的应用开发人员来说,本文可以帮助他们了解他们所使用的 API 背后的实现.对于 Android 的系统开发人员来说,本文可以帮助他们更好的了解 Android 系统架构. 定位服务是移动设备上最常用的功能之一,下文以 Android 源码为基础,详细分析了 Android 系统中定位服务的架构和实现. 定位服务是 Android 系统提供的一项系统服务,在 Android 系统中,所有系统服务的架构都是类似的.只要明白其中一个,然后再去理解其他是很容易的. 对于 Andro

在Win7系统中添加打印机的方法图解教程

  操作步骤 对于新购置的打印机,都有驱动光盘,所以我们这里不再赘述怎么安装新的打印机.我们这里介绍安装型号较早的打印机或是网络打印机的办法.在开始菜单当中,找到打印机选项,在框体上面的横栏当中,可以找到添加打印机的按钮. 按钮点击后会弹出一个向导程序,询问用户是添加本地的USB打印机还是网络或是无线打印机,由于Windows7操作系统在内部已经内置了大量的打印机驱动程序,所以如果不是极其冷门的产品,剩下的步骤都会自动安装驱动,这里我们演示怎么添加网络打印机. 这时候操作系统会自动扫描整个局域网

Win7系统中查看系统日志的方法教程

  Windows日志位于计算机管理的事件查看器中,用于存储来自旧版应用程序的事件以及适用于整个系统的事件. Win7系统的Windows日志包括五个类别,分别为应用程序日志.安全日志.系统日志.安装程序日志和转发事件日志. 应用程序日志包含由应用程序记录的事件;安全日志包含系统的登录.文件资源的使用以及与系统安全相关的事件;系统日志包含 Windows 系统组件记录的事件;安装程序日志包含与应用程序安装有关的事件;转发事件日志用于存储从远程计算机收集的事件. 下面就来看看如何查看Windows

win7系统在wps文档中添加图表的方法

  win7系统在wps文档中添加图表的方法: 1.首先点击电脑桌面上的WPS文字快捷键,打开WPS文字文档并新建一个WPS文字文档; 2.在WPS文字文档的功能选项里有插入选项,点击插入弹出插入功能选项下的菜单.菜单里有表格选项; 3.点击表格选项,弹出表格下拉菜单,可直接通过插入表格下方的小方格直接绘制要插入的表格,也可通过下方的插入表格选项进行表格插入. 4.在这里我们点击下方的插入表格选项,弹出插入表格对话框,选择要插入表格的行数和列数.比如我们要建立一个15行5列的表格,在行数上输入1

系统联系人-android中如何向系统中添加联系人数据

问题描述 android中如何向系统中添加联系人数据 以下是我的代码,但是总是添加的时候程序会崩溃,也没有错误的日志,麻烦哪位大神帮忙一下 ContentValues values = new ContentValues(); //先向RawContact.CONTENT_URI执行一个控制插入,目的是获得系统返回的rawContacctId Uri rawContactUri = this.getApplicationContext().getContentResolver() .insert

Android系统中 ActivityManager 是如何绑定系统的后台服务的?

问题描述 Android系统中 ActivityManager 是如何绑定系统的后台服务的? Android系统中 ActivityManager 是如何绑定系统的后台服务的? 解决方案 建议你去看下Android源代码.还有老罗那本书对这个有介绍! 解决方案二: binder,用aidl写的那个

如何从网络服务器中下载数据及针对数据操作的方法到android系统中并执行?

问题描述 如何从网络服务器中下载数据及针对数据操作的方法到android系统中并执行? 有几千组数据和针对数据操作的方法,每组的数据和方法都不相同.每次仅需下载其中的几组.该方法要在android上执行,不知如何实现? 如果用SQLite数据库存贮数据,触发器来实现针对数据操作的方法,android只需从SQLite数据库中取数据.但这样一方面担心某些方法太复杂,触发器实现不了.另一方面担心响应速度过慢. 不知android下可否把不同的代码封装成windows下的DLL文件一样?这样需要哪个就

android 5.1版本如何在系统中添加紧急号码

问题描述 android 5.1版本如何在系统中添加紧急号码 android 5.1版本我要在系统中添加"111"为紧急号码 解决方案 http://zhidao.baidu.com/link?url=Y34nl0-1Yfex2NNKwNfeyztv3zsLgjBUgl-xB_Cfi_34nWMdDvfdzzefukmSHnDG_xjyGACsHA1izjkSuWfuJsnei5ZONlf3v9ArEn50ESy 解决方案二: android5.1系统TvSettings为选择项添加背

Android系统中的进程管理:进程的创建

对于操作系统来说,进程管理是其最重要的职责之一. 考虑到这部分的内容较多,因此会拆分成几篇文章来讲解. 本文是进程管理系统文章的第一篇,会讲解Android系统中的进程创建. 本文适合Android平台的应用程序开发者,也适合对于Android系统内部实现感兴趣的读者. 概述 Android系统以Linux内核为基础,所以对于进程的管理自然离不开Linux本身提供的机制.例如: 通过fork来创建进行 通过信号量来管理进程 通过proc文件系统来查询和调整进程状态等 对于Android来说,进程