Android APP通過JNI直接訪問硬件框架

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;
}

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章