uniapp开发app框架在提升开发效率中的独特优势与应用探索
1067
2022-11-22
android jni的编写, 控制led灯
前言
jni的写法有好几种,在这里先介绍在android源码包+linux环境下的jni编程方式,随后会介绍ndk中的jni的编程方式。
一, JNI简介
jni, java native interface, java的本地接口,如果java代码想去调用native方法(实际就是c/c++函数),就需要用jni技术,在传统的java中jni技术就已经存在,但是由于传统的java代码中,不太去写架构或者平台相关的代码,所以以前jni不是太惹人注意,直到android出现后,android本身是一个linux操作系统, linux中的应用编程中就使用c/c++代码去调用驱动,假如android的应用apk想去调用底层的设备驱动,那么就必须要去调用c/c++代码,所以此时jni就显得很重要,它起着承上启下的作用.
二,JNI控制Led框架
编程之前首先需要给大家介绍一个大体的框架,我们需要在apk中去点一个led灯,此时就像做饭一样,介绍几个主料:
1, apk,实现button点灯
2, jni代码,调用linux的系统调用,去控制驱动
3, 驱动,完成控制led硬件
三, apk中使用jni中的接口
接口1: 调用动态库
static{
System.loadLibrary("led_jni"); // /system/lib/libled_jni.so
}
public native int OpenDev();
public native int DevOn();
public native int DevOff();
public native int CloseDev();
接口3: 直接调用本地方方法
OpenDev();
APP调用JNI代码非常简单
四,jni代码的编写
1, 原理
java中调用c代码的基本原理是通过查看一个映射表来完成的,比如java中调用OpenDev方法时,实际是有一个c/c++函数与它一一对应,所以需要一个映射表,并且将其注册给dvm,当dvm解析java中的native方法是,会去查看这个映射表,并执行对应的c/c++函数,同时jni代码所在的文件是需要编译成动态库,
2, 代码编写
jni代码可以写成c文件或者是cpp文件,但是建议大家写成cpp文件,在此,以下代码是写成一个文件led_jni.cpp
#define LOG_TAG "MyLed_jni"#include
3, jni代码重点介绍
a, 动态库中的接口:
a, 获取dvm的环境变量对象,并测试jni的版本(1.4)
vm->GetEnv((void **)&env, JNI_VERSION_1_4)
该方法是dvm给我们提供的方法,用于获取环境变量对象JNIEnv* env,同时会检测jni的版本是否是1.4, 该方法正常返回JNI_OK
b, 映射表的注册,会调用env->RegisterNatives()方法
env->RegisterNatives(jclass clazz, const JNINativeMethod* methods,jint nMethods)
第一个参数: 将java中native修饰的方法所在的类转换成jni的class类型(jclass)
jclass mycls = env->FindClass("com/hq/JniLedTestActivity");
env->FindClass中的参数是java中的native方法所在包和类的路径,这个是必须要注意的,路径是用Linux常用的路径表示方式,而不是用windows,也不是用java中的点分方式,同时路径必须要指定正确,否则会出错
第二个参数: jni的映射表, 实际是一个结构体数组, 结构体如下所示:
typedef struct { const char* name; // java的native修饰的方法名 const char* signature; // 方法的返回值和参数的描述,比如(I)I,表示返回值为int,带有一个int型的参 数 void* fnPtr; //c/c++中的函数名 } JNINativeMethod;
第三个参数: 映射表表的成员个数sizeof(myMethods)/sizeof(myMethods[0])
返回: JNI_OnLoad正常 返回JNI_VERSION_1_4, 错误返回一个负数
c, 接下来就是c/c++函数的实现了
static int fd = -1;jint open_led(JNIEnv *env, jobject thiz){ LOGD("----^_^ %s------\n", __FUNCTION__); fd = open("/dev/led1", O_RDWR); if(fd < 0) { LOGE("open : %s\n", strerror(errno)); return -1; } return 0;}
五,驱动部分
对于不同平台,led的驱动的写法是不一样的,但是基本的写法就是按照字符设备的方式去写,这个算是一个字符设备驱动的简单模板,基于s5pv210, 可以参考一下看看
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~