赞
踩
framework主要向上提供JAVA接口用于访问硬件设备,
进入到frameworks\base\services\core\jni文件夹中,新建com_android_server_HelloxjqService.cpp文件。com_android_server表示硬件服务Helloxjqservice放在frameworks/base/services/java目录下的com/android/server目录的,这儿HelloxjqService是一个提供JAVA接口的硬件访问服务类。
#define LOG_TAG "HelloxjqService" #include "JNIHelp.h" #include "jni.h" #include <utils/Log.h> #include <utils/misc.h> #include <utils/String8.h> #include <dirent.h> #include <fcntl.h> #include <stdio.h> #include <string.h> #include <sys/epoll.h> #include <sys/timerfd.h> #include <sys/types.h> #include <sys/socket.h> #include <arpa/inet.h> #include <netinet/in.h> #include <stdlib.h> #include <errno.h> #include <unistd.h> #include <linux/ioctl.h> #include <linux/rtc.h> #include <hardware/helloxjq.h> #include <fcntl.h> #include <stdio.h> #include<malloc.h> #include <hardware/hardware.h> namespace android { //jstring to char* char* jstringTostring(JNIEnv* env, jstring jstr); //char* to jstring jstring stoJstring(JNIEnv* env, const char* pat); /*在硬件抽象层中定义的硬件访问结构体,参考<hardware/helloxjq.h>*/ struct helloxjq_device_t* device = NULL; /*通过硬件抽象层定义的硬件访问接口读字符串*/ static jstring helloxjq_readString(JNIEnv* env, jobject clazz) { jstring ret; if(!device) { ALOGI("Helloxjq JNI: device is not open."); return NULL; } char *read_str = (char*)malloc(10); device->read_string(device, &read_str); ALOGI("Helloxjq JNI: read string %s from helloxjq device.", read_str); ret = stoJstring(env,read_str); free(read_str); read_str = NULL; return ret; } /*通过硬件抽象层定义的硬件访问接口写字符串*/ static jint helloxjq_writeString(JNIEnv* env, jobject clazz,jstring str) { if(!device) { ALOGI("Helloxjq JNI: device is not open."); return -1; } char * local_str = jstringTostring(env,str); device->write_string(device, local_str); ALOGI("Helloxjq JNI: write string %s to helloxjq device.", local_str); return sizeof(local_str); } /*通过硬件抽象层定义的硬件模块打开接口打开硬件设备*/ static inline int helloxjq_device_open(const hw_module_t* module, struct helloxjq_device_t** device) { return module->methods->open(module, HELLOXJQ_HARDWARE_MODULE_ID, (struct hw_device_t**)device); } /*通过硬件模块ID来加载指定的硬件抽象层模块并打开硬件*/ static jboolean helloxjq_init(JNIEnv* env, jclass clazz) { helloxjq_module_t* module; ALOGI("Helloxjq JNI: initializing......"); if(hw_get_module(HELLOXJQ_HARDWARE_MODULE_ID, (const struct hw_module_t**)&module) == 0) { ALOGI("Helloxjq JNI: helloxjq Stub found."); if(helloxjq_device_open(&(module->common), &device) == 0) { ALOGI("Helloxjq JNI: helloxjq device is open."); return 0; } ALOGI("Helloxjq JNI: failed to open helloxjq device."); return -1; } ALOGI("Helloxjq JNI: failed to get helloxjq stub module."); return -1; } /*JNI方法表*/ static const JNINativeMethod method_table[] = { {"init_native", "()Z", (void*)helloxjq_init}, {"readString_native", "()Ljava/lang/String;", (void*)helloxjq_readString}, {"wirteString_native", "(Ljava/lang/String;)I", (void*)helloxjq_writeString}, }; /*注册JNI方法*/ int register_android_server_HelloxjqService(JNIEnv *env) { ALOGI("SystemServer :register_android_server_HelloxjqService."); return jniRegisterNativeMethods(env, "com/android/server/HelloxjqService", method_table, NELEM(method_table)); } //jstring to char* char* jstringTostring(JNIEnv* env, jstring jstr) { char* rtn = NULL; jclass clsstring = env->FindClass("java/lang/String"); jstring strencode = env->NewStringUTF("utf-8"); jmethodID mid = env->GetMethodID(clsstring, "getBytes", "(Ljava/lang/String;)[B"); jbyteArray barr= (jbyteArray)env->CallObjectMethod(jstr, mid, strencode); jsize alen = env->GetArrayLength(barr); jbyte* ba = env->GetByteArrayElements(barr, JNI_FALSE); if (alen > 0) { rtn = (char*)malloc(alen + 1); memcpy(rtn, ba, alen); rtn[alen] = 0; } env->ReleaseByteArrayElements(barr, ba, 0); return rtn; } //char* to jstring jstring stoJstring(JNIEnv* env, const char* pat) { jclass strClass = env->FindClass("java/lang/String"); jmethodID ctorID = env->GetMethodID(strClass, "<init>", "([BLjava/lang/String;)V"); jbyteArray bytes = env->NewByteArray(strlen(pat)); env->SetByteArrayRegion(bytes, 0, strlen(pat), (jbyte*)pat); jstring encoding = env->NewStringUTF("utf-8"); return (jstring)env->NewObject(strClass, ctorID, bytes, encoding); } };
进入到frameworks/base/core/java/android/os目录,添加 IHelloxjqService.aidl 文件:
package android.os;
interface IHelloxjqService {
int wirteString(String str);
String readString();
}
进入到 frameworks/base/services/java/com/android/server 目录,添加 HelloxjqService.java 文件:
package com.android.server; import android.content.Context; import android.os.IHelloxjqService; import android.util.Slog; public class HelloxjqService extends IHelloxjqService.Stub { private static final String TAG = "HelloxjqService"; HelloxjqService() { init_native(); } public int wirteString(java.lang.String str){ return wirteString_native(str); } public java.lang.String readString() { return readString_native(); } private static native boolean init_native(); private static native int wirteString_native(String str); private static native String readString_native(); };
修改frameworks/base/services/jni目录下的 onload.cpp 文件,在 JNI_OnLoad函数中的return之前添加下面一句:
register_android_server_HelloxjqService(env);
在namespace中添加
int register_android_server_HelloxjqService(JNIEnv* env);
这样,在系统初始化时,就会调用register_android_server_HelloxjqService方法来加载JNI方法了。
在同目录下的Android.mk中在LOCAL_SRC_FILES变量中增加$(LOCAL_REL_DIR)/com_android_server_HelloxjqService.cpp \
进入到 frameworks/base 目录,打开 Android.mk 文件,在 LOCAL_SRC_FILES 变量中加入这么一行:注:一定要在LOCAL_SRC_FILES变量中
core/java/android/os/IHelloxjqService.aidl \
打开frameworks/base/services/java/com/android/server 目录下的 SystemServer.java 文件,
添加头文件import com.android.server.HelloxjqService;
在其中的 run() 函数中找到
try {
Slog.i(TAG, "DiskStats Service");
ServiceManager.addService("diskstats", new DiskStatsService(context));
} catch (Throwable e) {
reportWtf("starting DiskStats Service", e);
}
这一段,在后面加上下面的代码:
try {
Slog.i(TAG, "Helloxjq Service");
ServiceManager.addService("helloxjq", new HelloxjqService());
} catch (Throwable e) {
Slog.e(TAG, "Failure starting Helloxjq Service", e);
}
mmm frameworks/base/services/core/jni/
make snod
mmm frameworks/base
mmm frameworks/base/services/java
make snod
我看到很多帖子说make snod有问题,如果出现奇奇怪怪的问题,就使用make clean清理一遍工程,直接整编。
本章节出现问题很可能会导致系统一直重启,这时,可以通过查看Log,查看相关服务是否启动。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。