学习深入理解android第一章

本博客内容来自《深入理解android卷一》

android分为三层:java层,JNI层,Native层

这里以MediaScanner为例:

java层:

public class MediaScanner
{
      staic{
            System.loadLibrary("media_jni");
            native_init();//调用native_init函数
      }
     ...
     public void scanDirectories(String[] directories,String volumnName){
     ......
     }
     //申明一个native函数。native为java的关键字,表示它将由jni层完成
     private static native final void native_init();
     private native void processFile(String path,String mimeType,MediaScannerClient client);
}

 JNI层:

代码位置:android_media_MediaScanner.cpp

static void android_media_MediaScanner_native_init(JNIEnv *env)
{
    jclass clazz;
   clazz = env->FindClass("android/media/MediaScanner");//java层文件代码路径
    ...
   fields.context = env->GetFieldID(clazz,"mNativeContext","I");
   ...
   return;
}
//这个函数是processsFile的JNI层实现
static void android_media_MediaScanner_processFile(JNIEnv *env,jobject thiz,jstring path,jstring mimetype,jobject client){
MediaScanner *mp = (MediaScanner *)env->GetIntField(thiz,fields.contenxt);
...
const char *pathStr = env->GetStringUTFChars(path,NULL);
...
if(mimeType){
   env->ReleaseStringUTFChars(mimeType,mimeTypeStr);
}

}

问题:native_init();层如何知道android_media_MediaScanner_native_init的位置

android.media.MediaScanner.native_init换算成android_media_MediaScanner_native_init

答:一共有两种方式注册

1、静态方法

 先编写JAVA代码,然后编译生成.class文件

使用javah -o output packagename.classname生成的output.h文件中,就申明了JNI函数

2、动态注册

在libmedia_jni.so实现JNI_OnLoad

jclass clazz = (*env)->FindcClass(env,className);

(*env)->RegisterNatives(env,clazz,gMethods,numMethods);

jint JNI_OnLoad(JavaVm *vm,void * reserved)

{

    JNI

}

猜你喜欢

转载自gdfdfg-tech.iteye.com/blog/2066995