参考:
http://blog.youkuaiyun.com/luoshengyang/article/details/6578352
http://blog.youkuaiyun.com/t5721654/article/details/7480696
http://zhmeup.iteye.com/blog/1119503
编译指令:
mmm frameworks/base 编译指定的模块
make snod重新打包system.img文件
make clean 删除编译生成的文件
make update-api 更新系统的API
(1) 定义通信接口
进入到frameworks/base/core/java/android/os目录,新增IHelloService.aidl接口定义文件。
cd frameworks/base/core/java/android/os
vim IHelloService.aidl
IHelloService.aidl文件内容:
package android.os;
interface IHelloService {
void setVal(int val);
int getVal();
}
(2) 添加接口到编译脚本
将aidl文件名添加到frameworks/base/目录下的Android.mk编译脚本文件中。修改LOCAL_SRC_FILES变量的值,增加IHelloService.aidl:
LOCAL_SRC_FILES += /
....................................................................
core/java/android/os/IVibratorService.aidl /
core/java/android/os/IHelloService.aidl /
core/java/android/service/urlrenderer/IUrlRendererService.aidl /
.....................................................................
(3) 编写服务类
进入到frameworks/base/services/java/com/android/server目录,新增
HelloService.java文件:
package com.android.server;
public class HelloService extendsIHelloService.Stub {
private int mVal;
public void setVal(int val) {
mVal = val;
}
public int getVal() {
return mVal;
}
}
(4) 注册自定义服务类
将自定义服务注册到SystemServer,使得开机过程中被添加。在framework/base/services/java/com/android/server目录(与服务类同目录)中,在SystemServer.java文件ServerThread::run函数中增加加载HelloService的代码:
@Override
public void run() {
....................................................................................
try {
Slog.i(TAG, "DiskStatsService");
ServiceManager.addService("diskstats",
newDiskStatsService(context));
} catch (Throwable e) {
Slog.e(TAG, "Failurestarting DiskStats Service", e);
}
try {
Slog.i(TAG, "HelloService");
ServiceManager.addService("hello",new HelloService());
} catch (Throwable e) {
Slog.e(TAG, "Failurestarting Hello Service", e);
}
......................................................................................
}
(5) Context类中增加静态变量(非必须)
在frameworks/base/core/java/android/content/Context.java中增加Service名称定义:
public static final String HELLO_SERVICE =" hello ";
(6) 编译生成系统镜像和类库
在工程中添加了自己定义的类及常量,系统的api没有更新,因此需要先在工程中make clean然后make update-api,之后再使用make编出来的固件及jar包就能包含自定义的接口。
(1. # source build/envsetup.sh
2. # lunch jj_6dq-user)-进入源码根目录即可先配置下环境
3. # make -j4 2>&1 | teebuild_sabresd_6dq_android.log
(7) 测试添加的系统服务
/out/target/product/jj_6dq目录中(jj_6q为指定的名称,在lunch命令中指定)有生成的系统镜像文件,将生成的系统镜像烧录到对应的设备上。
out/target/common/obj/JAVA_LIBRARIES/framework_intermediates目录中,有系统的jar包:classes.jar。将此jar包以library的方式导入到IDE,即可使用新增加的和修改的类(此方法可以在IDE编写系统级应用时,解决隐藏类和方法的错误提示问题)。
private IHelloService helloService = null;
helloService =IHelloService.Stub.asInterface(ServiceManager
.getService(Context.HELLO_SERVICE));
int value = helloService.getVal();
helloService.setVal(value);
问题一:放在libs文件夹下,右击->Build Path->Add to Build Path,此在编译时会报错。解决方式是:新建library文件夹,将.jar文件放到该文件夹下,将其添加到编译路径。
问题二:在使用Context类时,找不到HELLO_SERVICE静态变量。原因是Build class path order不对,具体说就是android.jar和classes.jar的导入顺序不对,应该将classes.jar的顺序放在android.jar之前。(注:要使用修改的类,而不是IDE的SDK中的类,也需要如此。如果android.jar在后面,只有要用的类在SDK中没有,classes.jar包中的类才会被使用。)
注意:测试应用需在添加了系统级服务的系统上运行,此非通用的应用。