在Android 源码中添加系统服务

  

  Android系统本身提供了很多系统服务,如WindowManagerService,PowerManagerService等。下面描述一下添加一个系统服务的具体步骤。

 

1.定义自定义系统服务接口

  撰写一个aidl文件,定义服务的接口,将在编译过程中通过aidl工具生成对应的Java接口。

  一般系统服务的aidl文件都放在framework\base\core\java\android\os目录中。

  以IMyTool.aidl为例。在.aidl中定义自己需要加入的方法,编写规则和java接口差不多。

2.添加aidl到编译脚本

  将aidl文件名添加到frameworks\base\目录下的Android.mk编译脚本文件中。如:

复制代码
1 LOCAL_SRC_FILES += \
2 
3 core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl\
4 
5 …\
6 
7 core/java/android/os/IMyTool.aidl\
8 
9 
复制代码

  IMyTool.aidl即加进去的aidl文件,加入后才能在make过程中编译到,否则将在后面的SystemServer添加系统服务时会报错提示找不到对应类。

3.实现添加的服务

  编写真正工作的服务类,继承IMyTool.Stub类(AIDL文件名.Stub,aidl生成的接口中的内部类,是一个Binder)。

  例如:

1 public class MyToolService extends IMyTool.Stub {
2 
3   //实现IMyTool.aidl中定义的接口。
4 
5 }

  服务类一般都放在framework\base\services\core\java\com\android\server目录中。

4.注册到SystemServer

  将自定义服务注册到SystemServer,使得开机过程中被添加。在framework\base\services\java\com\android\server目录中的SystemServer中启动服务代码处加入:

  在SystemServer.java中,分不同类型的服务启动。

复制代码
 1     // Start services.
 2     try {
 3         startBootstrapServices();
 4         startCoreServices();
 5         startOtherServices();
 6     } catch (Throwable ex) {
 7         Slog.e("System", "******************************************");
 8         Slog.e("System", "************ Failure starting system services", ex);
 9         throw ex;
10     }
复制代码

  根据自定义服务类型加入到相应函数中:

复制代码
 1 try {
 2 
 3   Slog.i(TAG, "MyToolService");
 4 
 5   ServiceManager.addService(Context.MY_TOOL_SERVICE,new MyToolService(context));// MyToolService构造函数自己定义,一般都会用到Context
 6 
 7 } catch(Throwable e) {
 8 
 9   Slog.e(TAG, "Failure startingMyToolService", e);
10 
11 }
复制代码

  上面代码中Context.MY_TOOL_SERVICE是自己在Context类中定义的常量,也就是给服务定义的名字,使用常量方便获取服务,而不需要记住注册服务时用的名字,且想换名字时只需改一个常量的值。

5.更新api

  由于在工程中添加了自己定义的类及常量,系统的api没有更新,因此需要先在工程中make clean然后make update-api,执行完后会发现frameworks\base\api\current.xml文件中多出自己定义的一些东西。current.xml这个文件包含了所有系统所有能被应用层使用的类及其方法等。之后再使用make编出来的固件及jar包就能包含自定义的接口。

6.使用自定义的系统服务

  将编出来的jar包通过lib方式导入工程。jar包位置:out\target\common\obj\JAVA_LIBRARIES\framework_intermediates\classes.jar
调用以下代码获取自定义服务:

  IMyTool myTool = IMyTool.Stub.asInterface(ServiceManager.getService(MY_TOOL_SERVICE));

  MY_TOOL_SERVICE即在Context中定义的常量。获取到myTool后就可以调用在aidl文件中定义的接口了。

 

posted @   f9q  阅读(1038)  评论(0编辑  收藏  举报
编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 【杂谈】分布式事务——高大上的无用知识?
历史上的今天:
2016-03-05 Android Touch(4)MotionEvent(*)
点击右上角即可分享
微信分享提示