標籤:des android style blog http io ar color 使用
1>>JNI結構 (Java代碼>JNI代碼>C/C++代碼)
2>>一個MediaScanner調用例子
1.java層:(載入函數庫 庫名由.mk檔案配置)
public class MediaScanner{ static { System.loadLibrary("media_jni");//載入類庫 native_init();//調用jni層代碼 } private static native final void native_init();}2 .jni層:靜態註冊(函數名對包名_類名_方法名)
static voidandroid_media_MediaScanner_native_init(JNIEnv *env)//jni代碼實現{ jclass clazz; clazz = env->FindClass("android/media/MediaScanner"); if (clazz == NULL) { jniThrowException(env, "java/lang/RuntimeException", "Can't find android/media/MediaScanner"); return; } fields.context = env->GetFieldID(clazz, "mNativeContext", "I"); if (fields.context == NULL) { jniThrowException(env, "java/lang/RuntimeException", "Can't find MediaScanner.mNativeContext"); return; }}
***************************************靜態註冊***********************************
java檔案:
/** * @author Lean @date:2014-11-29 */public class GetStr {static{System.loadLibrary("JNISample");}public static native String testGet();}
>>擷取jni的.h代碼檔案
產生.h檔案,調用javah -jni packagename.classname
/* DO NOT EDIT THIS FILE - it is machine generated */#include <jni.h>/* Header for class com_example_jnisample_GetStr */#ifndef _Included_com_example_jnisample_GetStr#define _Included_com_example_jnisample_GetStr#ifdef __cplusplusextern "C" {#endif/* * Class: com_example_jnisample_GetStr * Method: testGet * Signature: ()Ljava/lang/String; */JNIEXPORT jstring JNICALL Java_com_example_jnisample_GetStr_testGet (JNIEnv *, jclass);#ifdef __cplusplus}#endif#endif
>>產生.so對應
書寫jni檔案,複製com_example_jnisample_GetStr.h檔案函數名到JNISample.cpp 如下:
#include <jni.h>#include "com_example_jnisample_GetStr.h"extern "C" {#endif/* * Class: com_example_jnisample_GetStr * Method: testGet * Signature: ()Ljava/lang/String; */JNIEXPORT jstring JNICALL Java_com_example_jnisample_GetStr_testGet (JNIEnv *env, jclass){return env->NewStringUTF("hello");}#ifdef __cplusplus}至此 ,可以通過調用java檔案調用到jni層,並在jni 層調用具體的c/c++代碼。
***************************************動態註冊***********************************
1.聲明gMethods(JNINativeMethod是一個java 函數與jni函數一一對應的結構體)
static JNINativeMethod gMethods[] = { {"processDirectory", "(Ljava/lang/String;Ljava/lang/String;Landroid/media/MediaScannerClient;)V", (void *)android_media_MediaScanner_processDirectory}, {"processFile", "(Ljava/lang/String;Ljava/lang/String;Landroid/media/MediaScannerClient;)V", (void *)android_media_MediaScanner_processFile}, {"setLocale", "(Ljava/lang/String;)V", (void *)android_media_MediaScanner_setLocale}, {"extractAlbumArt", "(Ljava/io/FileDescriptor;)[B", (void *)android_media_MediaScanner_extractAlbumArt}, {"native_init", "()V", (void *)android_media_MediaScanner_native_init}, {"native_setup", "()V", (void *)android_media_MediaScanner_native_setup}, {"native_finalize", "()V", (void *)android_media_MediaScanner_native_finalize},};
1-1.第2個參數方法類型簽名的簡化
2.註冊代碼的實際調用:
// This function only registers the native methods, and is called from// JNI_OnLoad in android_media_MediaPlayer.cppint register_android_media_MediaScanner(JNIEnv *env){ return AndroidRuntime::registerNativeMethods(env, "android/media/MediaScanner", gMethods, NELEM(gMethods));}3.在android_media_MediaPlayer.cpp中聲明方法,並在JNI_OnLoad中綁定,在System.loadLibrary()中調用後自動調用JNI_OnLoad()
>>android_media_MediaPlayer.cpp 聲明
extern int register_android_media_MediaScanner(JNIEnv *env);
>>JNI_OnLoad()調用
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("ERROR: GetEnv failed\n"); goto bail; } assert(env != NULL); if (register_android_media_MediaScanner(env) < 0) { LOGE("ERROR: MediaScanner native registration failed\n"); goto bail; } /* success -- return valid version number */ result = JNI_VERSION_1_4;bail: return result;}
3>>對應類型轉換
4>>JNIEnv (與線程相關的一個JNI環境結構體)
1)JNIEnv操作jobject相當於操作jfieldID和jmethodID
擷取methodID
調用mEnv操作(Call<Type>Method) methodID
擷取fieldID
5>>記憶體回收機制 變數生命週期 (全域引用 局部引用弱全域引用)
全域引用:NewGlobalRef聲明mClient(env->NewGlobalRef(client))
DeleteGlobalRef 銷毀mEnv->DeleteGlobalRef(mClient);
弱全域引用:特殊的全域引用使用前調用JNIEnv->IsSameOject判斷是否被回收
6>>jstring java中String 對象在jni 中的影射
本地字串轉JAVA 的String
Unicode:JNIEnv->NewString();
UTF-8:JNIEnv->NewStringUTF();
JAVA 的String轉本地字串
Unicode:JNIEnv->GetStringCharas();
UTF-8:JNIEnv->GetStringUTFCharas();
釋放資源:
Unicode:JNIEnv->ReleaseStringCharas();
UTF-8:JNIEnv->ReleaseStringUTFCharas();
Android-JNI總結(1)