Android-JNI總結(1)

來源:互聯網
上載者:User

標籤: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)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.