1 APP应用程序调用HardControl.java类中的方法
2.1 HardControl.java类中的方法通过系统调用System.loadLibrary("hardcontrol")来加载C库
public class HardControl {
static {
try {
System.loadLibrary("hardcontrol");
} catch (Exception e) {
e.printStackTrace();
}
}
}
2.2 HardControl.java类申明native本地方法供app java应用程序调用
public class HardControl {
public static native int ledCtrl(int which, int status);
public static native int ledOpen();
public static native void ledClose();
}
3 C库实现对应硬件的控制(open,read,write)
HardControl.java类中申明的native本地方法通过JNI将HardControl.c中实现的本地函数关联起来
HardControl.java 《==========》 HardControl.c
申明native本地方法 实现并注册对应的native函数
App应用程序
1.将申明本地方法的java类导入进来
import com.thisway.hardlibrary.*;
2.new申明native的类
一旦该类被使用,则该类的静态块static{}就会被调用
HardControl.java类中静态块代码通过系统调用System.loadLibrary("hardcontrol")来加载C库
如何加载C库:
2.1 将HardControl.c编译成so动态库
2.2 将生产的动态库HardControl.so编译进apk,或者放到/vendor/lib或者/system/lib路径下
如何将动态库编译进apk
2.2.1 将动态库HardControl.so文件放到app工程路径下的app/libs/armeabi/路径下
2.2.2 然后编译生成apk文件
HardControl hardcontorl = new HardControl();
3.调用类里面申明的native方法
MainActivityApp.java
import xxx.xx.x
HardControl.java
package com.thisway.hardlibrary;
public class HardControl {
public static native int ledCtrl(int which, int status);
public static native int ledOpen();
public static native void ledClose();
static {
try {
System.loadLibrary("hardcontrol");
} catch (Exception e) {
e.printStackTrace();
}
}
}
HardControl.c
在系统调用加载C库的时候会调用JNI_OnLoad(JavaVM *jvm, void *reserved)
通过(*env)->FindClass(env, "com/thisway/hardlibrary/HardControl")找到对应加载它的类
通过(*env)->RegisterNatives(env, cls, methods, sizeof(methods)/sizeof(methods[0])
将类中申明的方法同C库中实现的函数关联起来
#include <jni.h> /* /usr/lib/jvm/java-1.7.0-openjdk-amd64/include/ */
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <android/log.h> /* liblog */
//__android_log_print(ANDROID_LOG_DEBUG, "JNIDemo", "native add ...");
#if 0
typedef struct {
char *name; /* Java里调用的函数名 */
char *signature; /* JNI字段描述符, 用来表示Java里调用的函数的参数和返回值类型 */
void *fnPtr; /* C语言实现的本地函数 */
} JNINativeMethod;
#endif
static jint fd;
jint ledOpen(JNIEnv *env, jobject cls)
{
fd = open("/dev/leds", O_RDWR);
__android_log_print(ANDROID_LOG_DEBUG, "LEDDemo", "native ledOpen : %d", fd);
if (fd >= 0)
return 0;
else
return -1;
}
void ledClose(JNIEnv *env, jobject cls)
{
__android_log_print(ANDROID_LOG_DEBUG, "LEDDemo", "native ledClose ...");
close(fd);
}
jint ledCtrl(JNIEnv *env, jobject cls, jint which, jint status)
{
int ret = ioctl(fd, status, which);
__android_log_print(ANDROID_LOG_DEBUG, "LEDDemo", "native ledCtrl : %d, %d, %d", which, status, ret);
return ret;
}
static const JNINativeMethod methods[] = {
{"ledOpen", "()I", (void *)ledOpen},
{"ledClose", "()V", (void *)ledClose},
{"ledCtrl", "(II)I", (void *)ledCtrl},
};
/* System.loadLibrary */
JNIEXPORT jint JNICALL
JNI_OnLoad(JavaVM *jvm, void *reserved)
{
JNIEnv *env;
jclass cls;
if ((*jvm)->GetEnv(jvm, (void **)&env, JNI_VERSION_1_4)) {
return JNI_ERR; /* JNI version not supported */
}
cls = (*env)->FindClass(env, "com/thisway/hardlibrary/HardControl");
if (cls == NULL) {
return JNI_ERR;
}
/* 2. map java hello <-->c c_hello */
if ((*env)->RegisterNatives(env, cls, methods, sizeof(methods)/sizeof(methods[0])) < 0)
return JNI_ERR;
return JNI_VERSION_1_4;
}