实例参考:

MediaScanner.java (frameworks/base/media/java/android/media/MediaScanner.java)

android_media_MediaScanner.cpp (frameworks/base/media/jni/android_media_MediaScanner.cpp

1, JNI 的调用关系:

Java------------------------ JNI ------------------------ Native

以 MediaScanner 为实例:

MediaScanner --------- libmedia_jni.so ------------- libmedia.so

2, 加载JNI 库:

public class MediaScanner{    static {        System.loadLibrary("media_jni");        native_init();    }    ....}

在调用Native的函数之前,需加载JNI库,一般在类的static中加载,调用System.loadLibrary();

在加载了相应的JNI库之后,若要使用相应的native函数,只需使用native声明需要被调用的函数:

    private native void processDirectory(String path, String extensions, MediaScannerClient client);    private native void processFile(String path, String mimeType, MediaScannerClient client);    public native void setLocale(String locale);

3, JNI层分析:

如Java层中调用native的processFile()在JNI层的实现:

static voidandroid_media_MediaScanner_processFile(JNIEnv *env, jobject thiz, jstring path, jstring mimeType, jobject client){    MediaScanner *mp = (MediaScanner *)env->GetIntField(thiz, fields.context);    if (path == NULL) {        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);        return;    }    const char *pathStr = env->GetStringUTFChars(path, NULL);    if (pathStr == NULL) {  // Out of memory        jniThrowException(env, "java/lang/RuntimeException", "Out of memory");        return;    }    const char *mimeTypeStr = (mimeType ? env->GetStringUTFChars(mimeType, NULL) : NULL);    if (mimeType && mimeTypeStr == NULL) {  // Out of memory        env->ReleaseStringUTFChars(path, pathStr);        jniThrowException(env, "java/lang/RuntimeException", "Out of memory");        return;    }    MyMediaScannerClient myClient(env, client);    mp->processFile(pathStr, mimeTypeStr, myClient);    env->ReleaseStringUTFChars(path, pathStr);    if (mimeType) {        env->ReleaseStringUTFChars(mimeType, mimeTypeStr);    }}


注册 JNINativeMethod:

static JNINativeMethod gMethods[] = {{    {"processFile",            "(Ljava/lang/String;Ljava/lang/String;                Landroid/media/MediaScannerClient;)V",   (void *)android_media_MediaScanner_processFile},};

调用 registerNativeMethods() 函数注册:

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

补充: Java中proceedFile是如何默认找到 JNI Native中的 processFile:

由于MediaScanner.java位于android.media包中,因此processFile的全路径名应该是:android.media.MediaScanner.processFile =====> android_media_MediaScanner.cpp 的路径名 -----这样就会形成一个匹配。

4, JNI 动态注册:

若是使用registerNativeMethods()动态注册JNI的, 在上层JAVA调用System.loadLibrary加载完JNI动态库后,接着会查找JNI动态库中的JNI_OnLoad()函数,然后在该函数中完成动态注册的工作:

extern int register_android_media_MediaScanner(JNIEnv *env);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_MediaPlayer(env) < 0) {        LOGE("ERROR: MediaPlayer native registration failed\n");        goto bail;    }    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;}


参考上述的实例,可以自己实现一个JAVA 调用JNI的例子。

更多相关文章

  1. C语言函数以及函数的使用
  2. ListView中使用线程实现无限加载
  3. 利用View.inflate加载xml
  4. Anko:Android 代码动态布局的新方案
  5. android中去掉空格--trim函数
  6. Android JNI学习笔记——so文件动态加载
  7. Android studio 串口通信(动态获取串口)
  8. android中实现指针滑动的动态效果
  9. Unity2019通过unity获取Android动态权限(不用在Android写插件)

随机推荐

  1. android_atomic_dec android_atomic_inc
  2. android中的对话框之二:各种系统对话框的
  3. Android(安卓)px转dip px转sp法则
  4. android 控制软键盘显示和隐藏
  5. Android(安卓)onTouchEvent, onClick及on
  6. Failed to resolve: com.android.support
  7. 关于 android 远程控制(pc 控制手机)
  8. Intent学习
  9. 浅谈Android的BaseAdapter适配器模式
  10. Android开发环境配置之ADT怪异问题