上一篇博文里分析了系统服务JNI调用的实现,这篇博文将一步步实现一个RadioManagerService里的JNI的调用。
定义native方法
首先,是要在RadioManagerService中增加一个native方法的定义。
private native void nativeTest();
增加register方法
在上一篇博文里,我指出,native函数的注册是在/framework/base/service/jni/onload.cpp文件的JNI_OnLoad()函数里进行的。所以,我们在这个文件里要做如下修改。
增加函数声明
在这个文件的开头那堆函数声明的后面,增加如下函数声明:
int register_android_server_radiomanagerservice(JNIEnv* env);
调用函数
在JNI_OnLoad()函数的那堆register函数调用的后面增加下面的代码:
register_android_server_radiomanagerservice(env);
新建JNI源文件
在framework/base/service/jni/下新建文件com_android_server_radiomanagerservice.cpp。并在framework/base/service/jni/Android.mk的末尾增加这个文件的声明:
LOCAL_SRC_FILES:= \
com_android_server_AlarmManagerService.cpp \
com_android_server_AssetAtlasService.cpp \
com_android_server_ConsumerIrService.cpp \
com_android_server_input_InputApplicationHandle.cpp \
com_android_server_input_InputManagerService.cpp \
com_android_server_input_InputWindowHandle.cpp \
com_android_server_LightsService.cpp \
com_android_server_power_PowerManagerService.cpp \
com_android_server_SerialService.cpp \
com_android_server_SystemServer.cpp \
com_android_server_UsbDeviceManager.cpp \
com_android_server_UsbHostManager.cpp \
com_android_server_VibratorService.cpp \
com_android_server_location_GpsLocationProvider.cpp \
com_android_server_location_FlpHardwareProvider.cpp \
com_android_server_connectivity_Vpn.cpp \
com_android_server_radiomanagerservice.cpp
这样编译的时候就会编译这个文件了。
实现register方法
这里就直接贴出com_android_server_radiomanagerservice.cpp的源码了,分析请参考上一篇博文。
#define LOG_TAG "timothy_jni"
#define LOG_NDEBUG 1
#include "JNIHelp.h"
#include "jni.h"
#include "utils.h"
#include "android_runtime/AndroidRuntime.h"
#include <android_runtime/Log.h>
#include <unistd.h>
#include <utils/Log.h>
namespace android {
// =====================================================================
// 测试函数
static void nativeTest(JNIEnv* env, jobject obj) {
ALOGD("nativeTest() is called");
}
static JNINativeMethod gRadioManagerServiceMethods[] = {
/* name, signature, funcPt */
{ "nativeTest", "()V", (void*) nativeTest }
};
int register_android_server_iflytek_radiomanagerservice(JNIEnv* env) {
int res = jniRegisterNativeMethods(env,
"com/android/server/RadioManagerService",
gRadioManagerServiceMethods, NELEM(gRadioManagerServiceMethods));
LOG_FATAL_IF(res < 0, "Unable to register native methods.");
return 0;
}
}
一点技巧
修改jni之后,是不需要完整编译的。直接在jni目录mm之后,会生成libandroid_servers.so。将这个so文件推导system/lib/下面重启之后就能直接使用了。