为Android硬件抽象层(HAL)模块编写JNI方法提供Java访问硬件服务接口
在上两篇文章中,我们介绍了如何为Android系统的硬件编写驱动程序,包括如何在Linux内核空间实现内核驱动程序和在用户空间实现硬件抽象层接 口。实现这两者的目的是为了向更上一层提供硬件访问接口,即为Android的Application Frameworks层提供硬件服务。我们知道,Android系统的应用程序是用Java语言编写的,而硬件驱动程序是用C语言来实现的,那 么,Java接口如何去访问C接口呢?众所周知,Java提供了JNI方法调用,同样,在Android系统中,Java应用程序通过JNI来调用硬件抽 象层接口。在这一篇文章中,我们将介绍如何为Android硬件抽象层接口编写JNI方法,以便使得上层的Java应用程序能够使用下层提供的硬件服务。
一. 参照在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序一文,准备好硬件抽象层模块,确保Android系统镜像文件system.img已经包含hello.default模块。
二. 进入到frameworks/base/services/jni目录,新建com_android_server_HelloService.cpp文件:
USER-NAME@MACHINE-NAME:~/Android$ cd frameworks/base/services/jni
USER-NAME@MACHINE-NAME:~/Android/frameworks/base/services/jni$ vi com_android_server_HelloService.cpp
在 com_android_server_HelloService.cpp文件中,实现JNI方法。注意文件的命令方 法,com_android_server前缀表示的是包名,表示硬件服务HelloService是放在frameworks/base /services/java目录下的com/android/server目录的,即存在一个命令为 com.android.server.HelloService的类。这里,我们暂时略去HelloService类的描述,在下一篇文章中,我们将回 到HelloService类来。简单地说,HelloService是一个提供Java接口的硬件访问服务类。
首先是包含相应的头文件:
- #define LOG_TAG "HelloService"
- #include "jni.h"
- #include "JNIHelp.h"
- #include "android_runtime/AndroidRuntime.h"
- #include <utils/misc.h>
- #include <utils/Log.h>
- #include <hardware/hardware.h>
- #include <hardware/hello.h>
- #include <stdio.h>
接着定义hello_init、hello_getVal和hello_setVal三个JNI方法:
- namespace android
- {
- /*在硬件抽象层中定义的硬件访问结构体,参考<hardware/hello.h>*/
- struct hello_device_t* hello_device = NULL;
- /*通过硬件抽象层定义的硬件访问接口设置硬件寄存器val的值*/
- static void hello_setVal(JNIEnv* env, jobject clazz, jint value) {
- int val = value;
- LOGI("Hello JNI: set value %d to device.", val);
- if(!hello_device) {
- LOGI("Hello JNI: device is not open.");
- return;
- }
- hello_device->set_val(hello_device, val);
- }
- /*通过硬件抽象层定义的硬件访问接口读取硬件寄存器val的值*/
- static jint hello_getVal(JNIEnv* env, jobject clazz) {
- int val = 0;
- if(!hello_device) {
- LOGI("Hello JNI: device is not open.");
- return val;
- }
- hello_device->get_val(hello_device, &val);
- LOGI("Hello JNI: get value %d from device.", val);
- return val;
- }
- /*通过硬件抽象层定义的硬件模块打开接口打开硬件设备*/
- static inline int hello_device_open(const hw_module_t* module, struct hello_device_t** device) {
- return module->methods->open(module, HELLO_HARDWARE_MODULE_ID, (struct hw_device_t**)device);
- }
- /*通过硬件模块ID来加载指定的硬件抽象层模块并打开硬件*/
- static jboolean hello_init(JNIEnv* env, jclass clazz) {
- hello_module_t* module;
- LOGI("Hello JNI: initializing......");
- if(hw_get_module(HELLO_HARDWARE_MODULE_ID, (const struct hw_module_t**)&module) == 0) {
- LOGI("Hello JNI: hello Stub found.");
- if(hello_device_open(&(module->common), &hello_device) == 0) {
- LOGI("Hello JNI: hello device is open.");
- return 0;
- }
- LOGE("Hello JNI: failed to open hello device.");
- return -1;
- }
- LOGE("Hello JNI: failed to get hello stub module.");
- return -1;
- }
- /*JNI方法表*/
- static const JNINativeMethod method_table[] = {
- {"init_native", "()Z", (void*)hello_init},
- {"setVal_native", "(I)V", (void*)hello_setVal},
- {"getVal_native", "()I", (void*)hello_getVal},
- };
- /*注册JNI方法*/
- int register_android_server_HelloService(JNIEnv *env) {
- return jniRegisterNativeMethods(env, "com/android/server/HelloService", method_table, NELEM(method_table));
- }
- };
注意,在hello_init函数中,通过Android硬件抽象层提供的hw_get_module方法来加载模块ID为HELLO_HARDWARE_MODULE_ID的硬件抽象层模块,其中,HELLO_HARDWARE_MODULE_ID是在<hardware/hello.h>中定义的。Android硬件抽象层会根据HELLO_HARDWARE_MODULE_ID 的值在Android系统的/system/lib/hw目录中找到相应的模块,然后加载起来,并且返回hw_module_t接口给调用者使用。在 jniRegisterNativeMethods函数中,第二个参数的值必须对应HelloService所在的包的路径,即 com.android.server.HelloService。
三. 修改同目录下的onload.cpp文件,首先在namespace android增加register_android_server_HelloService函数声明:
namespace android {
..............................................................................................
int register_android_server_HelloService(JNIEnv *env);
};
为Android硬件抽象层(HAL)模块编写JNI方法提供Java访问硬件服务接口的更多相关文章
- 在Ubuntu为Android硬件抽象层(HAL)模块编写JNI方法提供Java访问硬件服务接口(老罗学习笔记4)
在上两篇文章中,我们介绍了如何为Android系统的硬件编写驱动程序,包括如何在Linux内核空间实现内核驱动程序和在用户空间实现硬件抽象层接口.实现这两者的目的是为了向更上一层提供硬件访问接口,即为 ...
- Android架构分析之使用自定义硬件抽象层(HAL)模块
作者:刘昊昱 博客:http://blog.csdn.net/liuhaoyutz Android版本:2.3.7_r1 Linux内核版本:android-goldfish-2.6.29 在上一篇博 ...
- Android Studio Xposed模块编写(二)
阅读本文前,假设读者已经看过Android Studio Xposed模块编写(一) 相关环境已经搭建完成.本文演示案例与上文环境一致,不在赘述. 1.概述 Xposed是非常牛叉的一款hook框架 ...
- 技术转载:Jni学习四:如何编写jni方法
转载:http://blog.chinaunix.net/u1/38994/showart_1099528.html 一.概述: 在这篇文章中将会简单介绍如何编制一些简单的JNI 方法.我们都知道JN ...
- Android硬件抽象层(HAL)深入剖析(一)【转】
作为一个搞android驱动或者说搞底层的人,我觉得对于hal那是必须要掌握的,而且必须达到一定深度,于是我总结了一下,将整个自己的分析思路写下来. 主要是看android源代码,根据源代码得到的思路 ...
- Android硬件抽象层(HAL)深入剖析(三)【转】
前面分析了android HAL层是如何搜索硬件模块的动态共享库的,其实就是在"system/lib/hw/"或者"/vendor/lib/hw/"这两个路径下 ...
- Android Studio Xposed模块编写(一)
1.环境说明 本文主要参考https://my.oschina.net/wisedream/blog/471292?fromerr=rNPFQidG的内容,自己实现了一遍,侵权请告知 已经安装xpos ...
- Android JNI编程(八)——体验AS2.2.2编写Jni程序、Java调C、C调Java函数、将C代码中的Log打印至Logcat
版权声明:本文出自阿钟的博客,转载请注明出处:http://blog.csdn.net/a_zhon/. 目录(?)[+] 不得不说在AS2.2以上的版本进行开发就一个字——爽,在2.0上使用jni出 ...
- Android硬件抽象层(HAL)深入剖析(二)【转】
上一篇我们分析了android HAL层的主要的两个结构体hw_module_t(硬件模块)和hw_device_t(硬件设备)的成员,下面我们来具体看看上层app到底是怎么实现操作硬件的? 我们知道 ...
随机推荐
- 安装asterisk
在centos6.5上: yum -y install lynx mysql-server mysql mysql-devel php php-mysql php-mbstring tftp-serv ...
- 判断手机电脑微信 js
if ((navigator.userAgent.match(/(MicroMessenger)/i))) { //微信浏览器 //location.href=""; } else ...
- HttpServletRequest对象(一)
一:HttpServletRequest介绍: 代表客户端的请求,当客户端通过HTTP协议访问服务器时,HTTP请求头中的所有信息都封装在这个对象中, 二:Request常用的方法 1):获得客户端信 ...
- 588. [NOIP1999] 拦截导弹
588. [NOIP1999] 拦截导弹 ★ 输入文件:missile.in 输出文件:missile.out 简单对比 时间限制:1 s 内存限制:128 MB 题目描述 某国为了防御敌国的导 ...
- 华为配置SSH登陆详细步骤
理解下SSH登录的过程: 1.建立目的端口为22的TCP连接 2.协商SSH版本 3.协商密钥和算法 4.会话建立 下面为server端的详细配置步骤: 1.创建本地RSA密钥对 rsa local- ...
- CDOJ 1324 卿学姐与公主 分块
题目地址 分块模板 #include<cstdio> #include<algorithm> #include<math.h> using namespace st ...
- python脚本文件删除
昨天有需求需要用python脚本删除一个目录下的文件.遇到了点麻烦. 使用的是shutil.rmtree(dir)函数,这个函数可以删除有内容的目录,而shutil.rmdir(dir)只能删除空目录 ...
- php给数组key:value中的key加引号
public function Ext_json_decode($str, $mode=false){ if(preg_match('/\w:/', $str)){ $str = preg_repla ...
- unity3d继续尝试
这一次完成了一些复杂的脚本,会了一些简单的鼠标事件,这样就能使用鼠标进行简单的交互了. 其实右边栏目上面一些奇怪的属性看的我是眼花缭乱. 也不知道干啥用的,还有就是真的很佩服里面的物理引擎确实简单易上 ...
- 网页特效-动态加载JavaScript
描述: 把一些逻辑独立的JavaScript脚本文件单独加载,是一种常见的JavaScript动态加载技术.可以减少不必要的JavaScript脚本文件的加载,以提高网页浏览速度 代码: <!D ...