Android JNI直接调用驱动程序

关于如何实现JNI请参考 Android JNI实现步骤


本例想测试一下,绕过硬件抽象层,直接在JNI中调用linux驱动程序。JNI的库有java应用程序加载,也就是本例直接是java应用程序通过JNI调用C程序,再通过C程序直接调用linux驱动程序。

#include "com_zhang_jni_test_JNITESTActivity.h"
#include 
#include
#include
#include

#define LOG_TAG "JNI_C"
#define DEVICE_NAME "/dev/hello"

int callDriver();
/*
 * Class:     com_zhang_jni_test_JNITESTActivity
 * Method:    nativeMethod
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_com_zhang_jni_test_JNITESTActivity_nativeMethod
  (JNIEnv *env, jobject obj)
{
        LOGI("JNI IN nativeMethod");

        jclass cls=(*env)->GetObjectClass(env,obj);
        static jmethodID mid = NULL;
        if(mid == NULL){
                mid=(*env)->GetMethodID(env,cls,"callBack","()V");
                if(mid == NULL){
                        return;
                }
        }
        (*env)->CallVoidMethod(env,obj,mid);

        LOGI("JNI CALL The Hello driver");
        callDriver();

}

int callDriver()
{
        int fd = -1;
        int val = 0;
        fd = open(DEVICE_NAME,O_RDWR);
        if(fd == -1){
                LOGI("Failed to open device %s .\n",DEVICE_NAME);
                return -1;
        }

        LOGI("Read original value:\n");

        read(fd,&val,sizeof(val));
        LOGI("%d\n\n",val);

        val = 5;
        LOGI("Write value %d to %s.\n",val,DEVICE_NAME);
        write(fd,&val,sizeof(val));

        LOGI("Read the value again:\n");
        read(fd,&val,sizeof(val));
        LOGI("%d\n\n",val);

        close(fd);

        return 0;
}
jint JNI_OnLoad(JavaVM* vm, void* reserved)
{
    void *venv;
    LOGI("JNI_OnLoad!");

    if ((*vm)->GetEnv(vm, (void**)&venv, JNI_VERSION_1_4) != JNI_OK) {
        LOGE("ERROR: GetEnv failed");
        return -1;
    }

     return JNI_VERSION_1_4;
}
上述代码中callDriver函数调用驱动程序。

驱动程序需具有一定权限。驱动程序的编写请参考相关书籍。


重新把生成的libInstanceMethodCall.so 考入开发版/system/lib目录下,重新安装原有的应用程序。

输出如下:

I/ActivityManager( 1228): Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=com.zhang.jni.test/.JNITESTActivity } from pid 1311
I/ActivityManager( 1228): Start proc com.zhang.jni.test for activity com.zhang.jni.test/.JNITESTActivity: pid=8417 uid=10032 gids={}
D/dalvikvm( 8417): Debugger has detached; object registry had 1 entries
I/JNI_C   ( 8417): JNI_OnLoad!
V/ZhangFang_JNITEST( 8417): Activity call Native Mehotd:
I/JNI_C   ( 8417): JNI IN nativeMethod
V/ZhangFang_JNITEST( 8417): Native method call the Activity methods
V/ZhangFang_JNITEST( 8417): ****************Native Method call back successfully!********
I/JNI_C   ( 8417): JNI CALL The Hello driver
I/JNI_C   ( 8417): Read original value:
I/JNI_C   ( 8417): 5
I/JNI_C   ( 8417): 
I/JNI_C   ( 8417): Write value 5 to /dev/hello.
I/JNI_C   ( 8417): Read the value again:
I/JNI_C   ( 8417): 5
I/JNI_C   ( 8417): 
I/ActivityManager( 1228): Displayed com.zhang.jni.test/.JNITESTActivity: +138ms
D/dalvikvm( 1311): GC_EXPLICIT freed 61K, 46% free 3160K/5767K, external 3137K/3867K, paused 25ms

调用驱动成功。


该方法虽然在效率上有点提升,但是不符合android框架,使用时需谨慎。

你可能感兴趣的:(android,系统开发)