Android:Java Native Interface入门

示例:

int size = (*env)->GetArrayLength(env, array); //获得数组array的长度 ,返回整型


jarray array = ((*env)->GetObjectArrayElement(env, array, i)); //获得对象数组array的元素i,

jint *pp = (*env)->GetIntArrayElements(env, (jintArray)array, 0 ); //获得整型数组array的元素0,返回指针jint*类型

(*env)->ReleaseIntArrayElements(env, (jintArray)array, pp,0 ); //释放整型数组array的元素pp,

(*env)->DeleteLocalRef(env,intArr); //释放内存 调用GetObjectArrayElement不需要释放,但用完需要调用DeleteLocalRef删除对应局部引用,如果作为返回值就不用删除。


在如下情况下,会用到类型之间的转换:


1java方法里面将参数传入本地方法;

2在本地方法里面创建java对象;

3在本地方法里面return结果给java程序。


JAVA类型与本地类型的对应关系:

Java类型    本地类型    字节(bit)

boolean     jboolean      8, unsigned
byte            jbyte              8
char           jchar             16, unsigned
short         jshort             16
int              jint                  32
long           jlong              64
float           jfloat              32 
double       jdouble        64
void            void               n/a
 java对象                  jobject

注意:在使用完你所转换之后的对象之后,必须调用ReleaseStringUTFChars方法,让JVM释放转换成UTF-8的string的对象的空间,

否则,JVM中会一直保存该对象,不会被垃圾回收器回收,导致内存溢出。


访问String的一些方法:

GetStringUTFChars     //将jstring转换成为UTF-8格式的char*


GetStringChars                //将jstring转换成为Unicode格式的char*


ReleaseStringUTFChars        //释放指向UTF-8格式的char*的指针


ReleaseStringChars          // 释放指向Unicode格式的char*的指针


NewStringUTF              //创建一个UTF-8格式的String对象


NewString               //创建一个Unicode格式的String对象


GetStringUTFLengt     //获取UTF-8格式的char*的长度


GetStringLength    // 获取Unicode格式的char*的长度


访问Array对象:

示例:

jintArray arr;

jsize len = (*env)->GetArrayLength(env, arr);    //1 获取数组的长度: 

jint *body = (*env)->GetIntArrayElements(env, arr, 0); // 2 获取指向arr数组元素0的指针

for (i=0; i<len; i++) {  sum += body[i];}          // 3  使用指针取出Array中的元素 

(*env)->ReleaseIntArrayElements(env, arr, body, 0); // 4释放数组元素的引用  提醒JVM回收arr数组元素的引用。


获取数组元素指针:

函数                                              数组类型

GetBooleanArrayElements      boolean
GetByteArrayElements              byte
GetCharArrayElements            char
GetShortArrayElements           short
GetIntArrayElements                  int
GetLongArrayElements             long
GetFloatArrayElements             float
GetDoubleArrayElements         double


释放数组元素指针:

函数                                                          数组类型

ReleaseBooleanArrayElements       boolean
ReleaseByteArrayElements               byte
ReleaseCharArrayElements              char
ReleaseShortArrayElements            short
ReleaseIntArrayElements                   int               
ReleaseLongArrayElements             long
ReleaseFloatArrayElements             float
ReleaseDoubleArrayElements          double

访问自定义Java对象数组

GetObjectArrayElement
SetObjectArrayElement


 访问Java对象

示例:

jclass cls = (*env)->GetObjectClass(env, obj);     // 1 获取你需要访问的Java对象的类: obj对应的jclass。

jmethodID mid = (*env)->GetMethodID(env, cls, "callback", "(I)V");     // 2 获取你要使用的方法的MethdoID。

其参数的意义:
  env-----JNIEnv
  cls-----第一步获取的jclass
  "callback"-----要调用的方法名
  "(I)V"-----方法的Signature签名(见后面)

(*env)->CallVoidMethod(env, obj, mid, depth);      //3 使用CallVoidMethod方法调用方法。

参数的意义:
  env-----JNIEnv
  obj----通过本地方法穿过来的jobject
  mid----要调用的MethodID(即第二步获得的MethodID)
  depth----方法需要的参数(对应方法的需求,添加相应的参数)

方法的Signature签名
方法的Signature是由方法的参数和返回值的类型共同构成的,结构为:
"(argument-types)return-type"

其中Java程序中参数类型和其对应的值如下:

Signature签名           Java中的类型

Z                                 boolean
B                                byte
C                                char
S                               short
I                                 int
J                               long
F                               float
D                              double
L                                fully-qualified-class //L类名
[                                 type  //数组
V                                void

一个Java类的方法的Signature签名可以通过javap命令获取:

javap -s -p Java类名



给调用的函数传参数:

通常我们直接在methodID后面将要传的参数添加在后面,但是还有其他的方法也可以传参数:

CallVoidMethodV                //获取一个数量可变的列表作为参数;
CallVoidMethodA              //获取一个union。

调用静态方法:
就是将第二步和第三步调用的方法改为对应的:

jmethodID GetStaticMethodID         //获取对应的静态方法的ID
CallStaticIntMethod                   // 调用静态方法

调用超类的方法:

CallNonvirtual<TYPE>Method
env->CallNonvirtualVoidMethod(p,clazz_Father,id_Father_function);          //调用父类方法 

访问Java对象的属性:

访问Java对象的属性和访问Java对象的方法基本上一样,只需要将函数里面的Method改为Field即可.

示例:

jclass objectClass = (env)->FindClass("com/sundy/jnidemo/DiskInfo");       //获得JAVA中的实例类
jfieldID fieldID = env->GetFieldID(native_clazz,"name","Ljava/lang/String;");      //获得域的ID
jint number= env->GetIntField(obj,fieldID);      //获得域属性
env->SetIntField(obj,fieldID,18880L) ;     //设置


不相关的额外函数:
char* jstringToWindows( JNIEnv *env, jstring jstr ); //将jstring类型转换成windows类型
jstring WindowsTojstring( JNIEnv* env, char* str ); //将windows类型转换成jstring类型
//将jstring类型转换成windows类型
char* jstringToWindows( JNIEnv *env, jstring jstr )
{
int length = (env)->GetStringLength(jstr );
const jchar* jcstr = (env)->GetStringChars(jstr, 0 );
char* rtn = (char*)malloc( length*2+1 );
int size = 0;
size = WideCharToMultiByte( CP_ACP, 0, (LPCWSTR)jcstr, length, rtn,(length*2+1), NULL, NULL );
if( size <= 0 )
return NULL;
(env)->ReleaseStringChars(jstr, jcstr );
rtn[size] = 0;
return rtn;
}
//将windows类型转换成jstring类型
jstring WindowsTojstring( JNIEnv* env, char* str )
{
jstring rtn = 0;
int slen = strlen(str);
unsigned short * buffer = 0;
if( slen == 0 )
rtn = (env)->NewStringUTF(str );
else
{
int length = MultiByteToWideChar( CP_ACP, 0, (LPCSTR)str, slen, NULL, 0 );
buffer = (unsigned short *)malloc( length*2 + 1 );
if( MultiByteToWideChar( CP_ACP, 0, (LPCSTR)str, slen, (LPWSTR)buffer, length ) >0 )
rtn = (env)->NewString( (jchar*)buffer, length );
}
if( buffer )
free( buffer );
return rtn;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值