实现源码下载链接 http://download.csdn.net/detail/hi_zhengjian/8794731
***方法一:直接在app里面通过JNI访问HAL层***
FmRadio应用代码结构如下:
一、FMRadio.java通过FmRadioService提供的服务通过JNI访问到HAL层:
FmRadioService实现IfmService的一些接口,以及提供一些供Client调用的接口,接口里面调用到JNI。
例如:
FmRadioService.java中private voidenableFmFacility(boolean bEnable)调用到
enableFmFacility_native。
enableFmFacility_native在com_android_server_FmService.cpp中实现,在映射表中注册,也就是所谓的JNI. 最终调用com_android_server_FmService.cpp中的android_FmService_enableFmFacility。
二、JNI简介:
传统的JNI需要遵循一定的命名规则,而Android改变了这种方式,可以通过以下两种方法把java层与C++层的代码进行映射,如下:
第一个参数是Java层的函数,第二个参数是函数的参数和返回类型也是属于java层,第三个参数是JNI实现的c++函数
static const JNINativeMethodgMethods[] = {
/* name, signature, funcPtr */
{ "enableFmFacility_native", "(Z)I", (void*)android_FmService_enableFmFacility },
{ "setFmCurrentFreq_native", "(II)I", (void*)android_FmService_setFmCurrentFreq },
{ "stationIsAvailable_native", "()Z", (void*)android_FmService_stationIsAvailable },
{ "fm_mute_native", "(I)I", (void*)android_FmService_fm_mute },
};
下面这个函数是将所有的映射函数进行注册
static int registerMethods(JNIEnv*env) {
static const char* const kClassName =
"com/rk/FmRadio/FmRadioService";
jclass clazz;
/* look up the class */
clazz = env->FindClass(kClassName);
if (clazz == NULL) {
return -1;
}
/* register all the methods */
if(env->RegisterNatives(clazz,gMethods,
sizeof(gMethods) /sizeof(gMethods[0])) != JNI_OK)
{
return -1;
}
/* fill out the rest of the ID cache */// .! :在 FM 实现中, 没有必要 cache Java 类 or field 的 ID.
return cacheIds(env,clazz);
}
然后需要重写JNI_OnLoad函数,这个函数一定要重载,当调用System.loadLibrary("rockchip_radio_jni");的时候,JVM启动的时候就会自动加载,并将我们的函数注册到系统JNI,以便调用。
jintJNI_OnLoad(JavaVM* vm, void* reserved) {
JNIEnv* env = NULL;
jint result = -1;
if (vm->GetEnv((void**) &env,JNI_VERSION_1_4) != JNI_OK) {
goto bail;
}
assert(env != NULL);
if(registerMethods(env) != 0) {
goto bail;
}
/* success -