前言:
准备记录一下自己的学习笔记,本文代码基于Android M 源码
1.编写AIDL
android/frameworks/base/core/java/android/os/ITestService.aidl
interface ITestService {
test();
}
2.修改mk文件
android/frameworks/base/Android.mk
LOCAL_SRC_FILES += \
core/java/android/os/ITestService.aidl
3.编写真正工作的服务类,继承ITestService.Stub类
(目前他并不是一个真正的服务,下面会通过SystemServer注册)
android/frameworks/base/services/core/java/com/android/server/TestService.java
public class TestService extends ITestService.Stub {
//实现ITestService.aidl中定义的接口。
test() {
//调用native方法
}
}
4.编写一个TestService管理类,TestServiceManager,方便app调用
android/frameworks/base/core/java/android/os/TestServiceManager.java
public class TestServiceManager {
private static final String TAG = "TestServiceManager";
private final ITestService mService;
public TestServiceManager() {
mService = ITestService.Stub.asInterface(
ServiceManager.getService("test"));
}
public TestServiceManager(Context context) {
super(context);
mService = ITestService.Stub.asInterface(
ServiceManager.getService("test"));
}
public void test() {
if (mService == null) {
Log.w(TAG, "Failed");
return;
}
try {
mService.test();
} catch (RemoteException e) {
Log.w(TAG, "Failed.", e);
}
}
}
5.将自定义服务注册到SystemServer,使得开机过程中被添加。
android/frameworks/base/services/java/com/android/server/SystemServer.java
简单看一下流程,从main函数进入,会调用自身的run方法
public static void main(String[] args) {
new SystemServer().run();
}
在run方法中,通过下面的方法启动:开机,核心,以及其他服务
private void run() {
...
// Start services.
try {
startBootstrapServices();
startCoreServices();
startOtherServices();
} catch (Throwable ex) {
Slog.e("System", "******************************************");
Slog.e("System", "************ Failure starting system services", ex);
throw ex;
}
...
}
因此可以把自己创建的service 添加到startOtherServices中
public final class SystemServer {
....
private void startOtherServices() {
....
TestService test = null;
....
Slog.i(TAG, "Test Service");
test = new TestService(context);
ServiceManager.addService("test", test);
//ServiceManager.addService(Context.TEST_SERVICE, test);
....
try {
test.systemReady();
} catch (Throwable e) {
reportWtf("making Test Service ready", e);
}
}
....
}
:另外可以把"test"字段,定义在Context中,方便从app中获取service
android/frameworks/base/core/java/android/content/Context.java
public static final String TEST_SERVICE = "test";
6.让app侧,可以通过getSystemService接口获得服务
android/frameworks/base/core/java/android/app/ContextImpl.java
通过查看getSystemService实现
@Override
public Object getSystemService(String name) {
return SystemServiceRegistry.getSystemService(this, name);
}
实际是通过SystemServiceRegistry.getSystemService来获取具体的服务
android/frameworks/base/core/java/android/app/SystemServiceRegistry.java
public static Object getSystemService(ContextImpl ctx, String name) {
ServiceFetcher<?> fetcher = SYSTEM_SERVICE_FETCHERS.get(name);
return fetcher != null ? fetcher.getService(ctx) : null;
}
private static final HashMap<String, ServiceFetcher<?>> SYSTEM_SERVICE_FETCHERS =
new HashMap<String, ServiceFetcher<?>>();
获取系统服务是通过ServiceFetcher的getService来获取的,并且SYSTEM_SERVICE_FETCHERS就是一个Map实例,所以肯定是通过put方法为它赋值的, 通过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);
}
所以在SystemServiceRegistry的static静态代码块中进行注册
static {
.....
registerService(Context.VIBRATOR_SERVICE, TestServiceManager.class,
new CachedServiceFetcher<TestServiceManager>() {
@Override
public Vibrator createService(ContextImpl ctx) {
return new TestServiceManager(ctx);
}});
.....
}
7.更新API
由于在工程中添加了自己定义的类及常量,系统的api没有更新,因此需要先在工程中make clean然后make update-api,执行完后会发现frameworks\base\api\current.xml文件中多出自己定义的一些东西。current.xml这个文件包含了所有系统所有能被应用层使用的类及其方法等。
之后再使用make编出来的固件及jar包就能包含自定义的接口。
最后:
在framework 添加自己的服务就算完了,向上为app提供接口,向下与HAL层交互。下一步准备学习一下framework与HAL层之间的桥梁JNI。