From here
Android系统本身提供了很多系统服务,如WindowManagerService,PowerManagerService等。下面描述一下添加一个系统服务的具体步骤。
1、 撰写一个aidl文件,定义服务的接口,将在编译过程中通过aidl工具生成对应的java接口。一般系统服务的aidl文件都放在framework\base\core\java\android\os目录中。
以我所写的IMyTool.aidl为例。在.aidl中定义自己需要加入的方法,编写规则和java接口差不多,这里不多说。
2、 将aidl文件名添加到frameworks\base\目录下的Android.mk编译脚本文件中。
如:
LOCAL_SRC_FILES += \
core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl\
…\
core/java/android/os/IMyTool.aidl\
…
IMyTool.aidl即我加进去的aidl文件,加入后才能在make过程中编译到,否则将在后面的SystemServer添加系统服务时会报错提示找不到对应类。
3、 编写真正工作的服务类,继承IMyTool.Stub类(AIDL文件名.Stub,aidl生成的接口中的内部类,是一个Binder)。
服务类一般都放在framework\base\services\java\com\android\server目录中。
例如:
public class MyToolService extends IMyTool.Stub {
实现IMyTool.aidl中定义的接口。
}
4、 将自定义服务注册到SystemServer,使得开机过程中被添加。
在framework\base\services\java\com\android\server目录中的SystemServer中启动服务代码处加入:
try {
Slog.i(TAG, "MyToolService");
ServiceManager.addService(Context.MY_TOOL_SERVICE,new MyToolService(context));// MyToolService构造函数自己定义,一般都会用到Context
} catch(Throwable e) {
Slog.e(TAG, "Failure startingMyToolService", e);
}
上面代码中Context.MY_TOOL_SERVICE是自己在Context类中定义的常量,也就是给服务定义的名字,使用常量方便获取服务,而不需要记住注册服务时用的名字,且想换名字时只需改一个常量的值。
5、 由于在工程中添加了自己定义的类及常量,系统的api没有更新,因此需要先在工程中make clean然后make update-api,执行完后会发现frameworks\base\api\current.xml文件中多出自己定义的一些东西。current.xml这个文件包含了所有系统所有能被应用层使用的类及其方法等。
之后再使用make编出来的固件及jar包就能包含自定义的接口。
编译后如何使用:
将编出来的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文件中定义的接口了。
From here
为Android添加Java层服务
同前一篇文章类似,此文旨在简单介绍一下如何在java层添加自己的服务,相关的理论网上已经有很多文章,在此不在详述。
Java层服务顾名思义即为从Java层提供的服务,它与C++层的服务不同之处在于其服务进程的运行由系统(ServiceManager)统一维护。在文件frameworks/base/services/java/com/android/server/SystemServer.java中我们可以看到以下代码:
AlarmManagerServicealarm= new AlarmManagerService(context);
ServiceManager.addService(Context.ALARM_SERVICE,alarm);
这个操作在系统启动时完成,由ServiceManager负责创建服务进程并运行之。所以我们要做的事就是实现一个java服务,并将其添加到这里并由系统运行起来,以下是具体实现步骤:
实现自己的java层service
1. 在目录
frameworks/base/core/java/android/os中增加自己的AIDL文件用来申明服务:
BelyService.aidl:
package android.os;
interface IBelyService {
/**
*
*/
int calculateSqu(int value);
}
2. 在目录
frameworks/base/services/java/com/android/server增加service的实现文件:
BelyService.java:
package com.android.server;
import android.content.Context;
import android.os.IBelyService;
public class BelyService extends IBelyService.Stub {
publicBelyService(Context context){
super();
}
publicint calculateSqu(int val){
return val*val;
}
}
3. 将java服务添加到ServiceManager中:
BelyService bs = new BelyService(context);
ServiceManager.addService("BelyService",bs);
自此,重新编译Android并运行,我们所创建的服务即可访问,下面是演示如何调用:
同样在package/apps下任意创建一个应用,调用服务的方法如下:
import android.os.ServiceManager;
import android.os.IBelyService;
IBelyService bs =IBelyService.Stub.asInterface(ServiceManager.getService("BelyService"));
int ret = bs.calculateSqu(9);
上面我们使用的是Android内部的方法来获取服务,当然也可以使用公开的API:context.getSystemService来获取。
谢谢!