一、首先介绍下AIDL文件
1、AIDL (Android Interface Definition Language )
2、AIDL 适用于 进程间通信,并且与Service端多个线程并发的情况,如果只是单个线程 可以使用 Messenger ,如果不需要IPC 可以使用Binder
3、AIDL语法:基础数据类型都可以适用,List Map等有限适用。static field 不适用。
4、AIDL基本用法
用法:命名为IRemoteService.aidl,放在com.example.android包下(这个可以随意),保存后Android编译器会在gen目录下自动生成IRemoteService.java文件。
以Led为例
1> 首先编写ILedService.aidl文件package android.os;
/** {@hide} */
interface ILedService
{
int ledCtrl(int which, int status);
}
2> 把 ILedService.aidl 放入 frameworks/base/core/java/android/os3> 修改 frameworks/base/Android.mk
添加一行
core/java/android/os/IVibratorService.aidl \
+ core/java/android/os/ILedService.aidl \
4> mmm frameworks/base
它会生成: ./out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/android/os/ILedService.java
AIDL文件的使用:
ILedService.aidl >> LedService >> ILedService.Stub.asInterface(ServiceManager.getService("led")) >> LedService.ledCtrl(0,1)
二、编写LedService.java
package com.android.server;
import android.os.ILedService;
public class LedService extends ILedService.Stub {
private static final String TAG = "LedService";
/* call native c function to access hardware */
public int ledCtrl(int which, int status) throws android.os.RemoteException
{
return native_ledCtrl(which, status);
}
public LedService() {
native_ledOpen();
}
public static native int native_ledOpen();
public static native void native_ledClose();
public static native int native_ledCtrl(int which, int status);
}
修改SystemServer.java添加服务
Slog.i(TAG, "Led Service");
ServiceManager.addService("led", new LedService());
上述两个步骤完成后把相应的文件替换至安卓源码里,所在目录:
frameworks/base/services/java/com/android/server/SystemServer.java
frameworks/base/services/core/java/com/android/server/LedService.java
三、修改JNI文件
首先修改com_android_server_LedService.cpp文件:#define LOG_TAG "LedService"
#include "jni.h"
#include "JNIHelp.h"
#include "android_runtime/AndroidRuntime.h"
#include <utils/misc.h>
#include <utils/Log.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
namespace android
{
static jint fd;
jint ledOpen(JNIEnv *env, jobject cls)
{
fd = open("/dev/leds", O_RDWR);
ALOGI("native ledOpen : %d", fd);
if (fd >= 0)
return 0;
else
return -1;
}
void ledClose(JNIEnv *env, jobject cls)
{
ALOGI("native ledClose ...");
close(fd);
}
jint ledCtrl(JNIEnv *env, jobject cls, jint which, jint status)
{
int ret = ioctl(fd, status, which);
ALOGI("native ledCtrl : %d, %d, %d", which, status, ret);
return ret;
}
static const JNINativeMethod methods[] = {
{"native_ledOpen", "()I", (void *)ledOpen},
{"native_ledClose", "()V", (void *)ledClose},
{"native_ledCtrl", "(II)I", (void *)ledCtrl},
};
int register_android_server_LedService(JNIEnv *env)
{
return jniRegisterNativeMethods(env, "com/android/server/LedService",
methods, NELEM(methods));
}
}
该文件作用是注册本地方法供LedService.java使用
int register_android_server_LedService(JNIEnv *env);
register_android_server_LedService(env);
完成两步后替换源码相应的文件目录为:
frameworks/base/services/core/jni/onload.cpp
frameworks/base/services/core/jni/com_android_server_LedService.cpp
修改 frameworks/base/services/core/jni/Android.mk :
$(LOCAL_REL_DIR)/com_android_server_VibratorService.cpp \
+ $(LOCAL_REL_DIR)/com_android_server_LedService.cpp \
编译:
$ mmm frameworks/base/services
$ make snod
$ ./gen-img.sh