Android JNI 学习笔记

1.     JNI 入门

      最近学习了下JNI,记录下感受。

JNI(Java NativeInterface), its objective is to call those function which has implemented inlower-level programming language, such as C, C++

Implement steps:

     S1. Write the JAVA classwith Native declaration

            public classCamcorderProfile{

               ……

               static {

                        System.loadLibrary("media_jni");

                         native_init();

                     }

              private staticnative final voidnative_init();

              private static native finalCamcorderProfile native_get_camcorder_profile(int cameraId, int quality);

              private static native final booleannative_has_camcorder_profile(

            int cameraId, int quality);}

        声明native方法:如果你想将一个方法做为一个本地方法的话,那么你就必须声明改方法为native的,并且不能实现。其中方法的参数和返回值在后面讲述。
  
   Load动态库:System.loadLibrary("media_jni");加载动态库(我们可以这样理解:我们的方法 native_init()没有实现,但是我们在下面就直接使用了,所以必须在使用之前对它进行初始化)这里一般是以static块进行加载 的。同时需要注意的是System.loadLibrary();的参数“media_jni”是动态库的名字。

      S2. 编写本地方法

static void

android_media_MediaScanner_native_init(JNIEnv*env)

 static JNINativeMethodgMethodsForCamcorderProfileClass[] = {  

{"native_init","()V", (void *)android_media_MediaScanner_native_init },

}

2.    JNI 流程

 

 

Windows系统上的java体系

                 java程序中则是jvm通过加载并调用此jni程序来间接地调用目标原生函数。

 

Jni调用过程示意图

3.    Android JNINativeMethod

a .JNINativeMethod

Andoird 中使用了一种不同传统Java JNI的方式来定义其native的函数。其中很重要的区别是Andorid使用了一种Java 和 C 函数的映射表数组,并在其中描述了函数的参数和返回值。这个数组的类型是JNINativeMethod,定义如下:

typedef struct{

const char* name;

const char* signature;

void* fnPtr;

} JNINativeMethod;


第一个变量name是Java中函数的名字。

第二个变量signature,用字符串是描述了函数的参数和返回值

第三个变量fnPtr是函数指针,指向C函数。

其中比较难以理解的是第二个参数,例如 

"()V"   void Func()

"(II)V" void Func(int, int)

"(Ljava/lang/String;Ljava/lang/String;)V"

具体的每一个字符的对应关系如下

字符  Java类型    C类型       长度

V    void    void    n/a

Z   jboolean boolean  8

I    jint    int     32

J    jlong   long    64

D    jdouble double  64

F    jfloat   float   32

B    jbyte    byte    8

C    jchar   char    16

S   jshort   short   16

数组则以”[“开始,用两个字符表示

[I jintArray int[]

[F jfloatArray float[]

[B jbyteArray byte[]

[C jcharArray char[]

[S jshortArray short[]

[D jdoubleArray double[]

[J jlongArray long[]

[Z jbooleanArray boolean[]

上面的都是基本类型。如果Java函数的参数是class,则以”L”开头,以”;”结尾中间是用”/” 隔开的包及类名。而其对应的C函数名的参数则为jobject. 一个例外是String类,其对应的类为jstring

Ljava/lang/String; String jstring

 

static JNINativeMethodgMethodsForCameraProfileClass[] = {

      {"native_init","()V",(void *)android_media_MediaProfiles_native_init},

      {"native_get_num_image_encoding_quality_levels","(I)I",                                   (void*)android_media_MediaProfiles_native_get_num_image_encoding_quality_levels},

      {"native_get_image_encoding_quality_level","(II)I",                   (void*)android_media_MediaProfiles_native_get_image_encoding_quality_level},

};

b.注册JNI

static const char* const kCamcorderProfileClassPathName ="android/media/CamcorderProfile";

int register_android_media_MediaProfiles(JNIEnv *env)

{ int ret2 = AndroidRuntime::registerNativeMethods(env,

                kCamcorderProfileClassPathName,

                gMethodsForCamcorderProfileClass,

                NELEM(gMethodsForCamcorderProfileClass)),

                                                 Return ret2;}

c.JNI_OnLoad

jint JNI_OnLoad(JavaVM* vm, void* reserved) {

JNIEnv* env = NULL;

jint result = -1;

LOGI("JNI_OnLoad");

if (register_android_media_MediaProfiles(env) < 0) {

LOGE("ERROR: MediaProfiles native registration failed");

goto fail;}

/* success -- return valid version number */

result = JNI_VERSION_1_4;

fail:

   return result;}

 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值