Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android 通過Jni調用Native

Android 通過Jni調用Native

編輯:關於Android編程

Native是java本地方法的聲明關鍵字,當在方法中調用一些不是由java語言寫的代碼或要直接操作計算機硬件或要提交某些代碼的運行效率時要聲明native方法.

Jni是java native interface的縮寫,從字面上來說就是java本地方法的接口,所以他就是提供java native方法的聲明和對上層的接口調用.


1.Jni 編寫

使用native 聲明_camera_open 為本地方法,並load與之相對應的動態鏈接庫.

	private native int _camera_open(int cameraId);
	private final static String studioLib = "studionative";
	
	public static boolean loadLibrarys() {
		Log.i(TAG, "loadLibrarys");
		boolean status = false;
		try{
			System.loadLibrary(studioLib);
			status = true;
		}catch(Exception e){
			Log.e(TAG, "exception:" + e.toString());
		}
		return status;
	}


          

2.使用javah -jni 命令 進入bin目錄下 javah -jni cn.jesse.studo.jni.StudioJni 生成一個cn_jesse_studio_jni_StudioJni.h文件,提供給native 使用.這裡不了解為什麼在生成的頭文件中的方法會被自動加個1.

/* DO NOT EDIT THIS FILE - it is machine generated */
#include 
#include 
#include AndroidRuntime.h>
#include 
#include 
#include 
#include 
#include 
#include 
#include "logger.h"
/* Header for class cn_jesse_studio_jni_StudioJni */

#ifndef _Included_cn_jesse_studio_jni_StudioJni
#define _Included_cn_jesse_studio_jni_StudioJni
#ifdef __cplusplus
int register_cn_jesse_studio_jni_studioJni(JNIEnv*);
extern "C" {
#endif
/*
 * Class:     cn_jesse_studio_jni_StudioJni
 * Method:    _camera_open
 * Signature: (I)I
 */
JNIEXPORT jint JNICALL Java_cn_jesse_studio_jni_StudioJni__1camera_1open
  (JNIEnv *, jobject, jint);

/*
 * Class:     cn_jesse_studio_jni_StudioJni
 * Method:    _serial_port_open
 * Signature: (Ljava/lang/String;IIIC)Ljava/io/FileDescriptor;
 */
JNIEXPORT jobject JNICALL Java_cn_jesse_studio_jni_StudioJni__1serial_1port_1open
  (JNIEnv *, jobject, jstring, jint, jint, jint, jchar);

/*
 * Class:     cn_jesse_studio_jni_StudioJni
 * Method:    _serial_port_close
 * Signature: ()I
 */
JNIEXPORT jint JNICALL Java_cn_jesse_studio_jni_StudioJni__1serial_1port_1close
  (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif
3.在cpp文件中實現之前在jni中聲明出來的native方法.這裡只是簡單的接收一個int數據返回一個int數據.參數中的JNIEnv 指針指向一個函數指針表,通過該指針可以訪問其中方法.jclass 在該方法是靜態的情況下是是一個類對象的引用,jclass在該方法是實例的情況下代表的是被調用方法所屬類的引用.

JNIEXPORT jint JNICALL media_camera_open(JNIEnv *env,jclass thiz,jint cameraId){
    LOGI(CAMERA_TAG, "media_camera_open");
    int status = -1;
    return status;
}
4.在native中聲明jni方法,綁定jni聲明方法和本地實現方法,注冊jni類,並實現加載Jni方法.

static const char* const cameraClassPathName = "cn/jesse/studio/jni/StudioJni";
static JNINativeMethod jniMethods[] = {
    {"_camera_open",             "(I)I",                                             (void *) media_camera_open},
    {"_serial_port_open",        "(Ljava/lang/String;IIIC)Ljava/io/FileDescriptor;", (void *) serial_port_open},
    {"_serial_port_close",       "()I",                                              (void *) serial_port_close}
};


int register_cn_jesse_studio_jni_studioJni(JNIEnv* env){
    return AndroidRuntime::registerNativeMethods(env, cameraClassPathName, jniMethods,sizeof(jniMethods) / sizeof(jniMethods[0]));
}
static int registerNatives(JNIEnv* env){
    if (register_cn_jesse_studio_jni_studioJni(env) < 0){
        LOGE(JNILOADER_TAG, "ERROR: registerNatives failed\n");
        return JNI_FALSE;
    }

    return JNI_TRUE;
}

jint JNI_OnLoad(JavaVM* vm, void* reserved) {
    JNIEnv* env = NULL;
    jint result = -1;
    if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
        LOGE(JNILOADER_TAG, "ERROR: GetEnv failed\n");
        goto bail;
    }
    if (env == NULL || registerNatives(env) != JNI_TRUE) {
        LOGE(JNILOADER_TAG, "JniLoad ERROR: registerNatives failed, env=%p", env);
        goto bail;
    }
    LOGI(JNILOADER_TAG, "JniLoad JNI Load Success");
    /* success -- return valid version number */
    result = JNI_VERSION_1_4;

    bail: return result;
}
5.返回值參數Jni映射.

Java 類型 本地類型 描述 boolean jboolean C/C++8位整型 byte jbyte C/C++帶符號的8位整型 char jchar C/C++無符號的16位整型 short jshort C/C++帶符號的16位整型 int jint C/C++帶符號的32位整型 long jlong C/C++帶符號的64位整型e float jfloat C/C++32位浮點型 double jdouble C/C++64位浮點型 Object jobject 任何Java對象,或者沒有對應java類型的對象 Class jclass Class對象 String jstring 字符串對象 Object[] jobjectArray 任何對象的數組 boolean[] jbooleanArray 布爾型數組 byte[] jbyteArray 比特型數組 char[] jcharArray 字符型數組 short[] jshortArray 短整型數組 int[] jintArray 整型數組 long[] jlongArray 長整型數組 float[] jfloatArray 浮點型數組 double[] jdoubleArray 雙浮點型數組


表B

函數 Java 數組類型 本地類型 GetBooleanArrayElements jbooleanArray jboolean GetByteArrayElements jbyteArray jbyte GetCharArrayElements jcharArray jchar GetShortArrayElements jshortArray jshort GetIntArrayElements jintArray jint GetLongArrayElements jlongArray jlong GetFloatArrayElements jfloatArray jfloat GetDoubleArrayElements jdoubleArray jdouble

表C

函數 描述 GetFieldID 得到一個實例的域的ID GetStaticFieldID 得到一個靜態的域的ID GetMethodID 得到一個實例的方法的ID GetStaticMethodID 得到一個靜態方法的ID

表D

Java 類型 符號 boolean Z byte B char C short S int I long L float F double D void V objects對象 Lfully-qualified-class-name;L類名 Arrays數組 [array-type [數組類型 methods方法 (argument-types)return-type(參數類型)返回類型

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved