- 在Jni中为什么会用到反射
- Java中的反射
- Jni中的反射得到字符串并显示
- 得到方法签名
在Jni中为什么会用到反射
因为java中的类型与C中的类型许多都不一样 例如java中的字符串类型的变量传进C中 由于java与C中的String类型不能通用 所以为了使用 从而引入了反射.
Java中的反射
在Java中我们是这样反射的.
public class Person{
public Person(){
}
public void test(){
}
private void test(String name){
System.out.println("私有方法"+name);
}
}
Person p = new Person();
Class clazz = Person.class
Method m = clazz.getMethod("test",null);//得到无参方法
m.invoke(p,null);//调用方法
Jni中的反射得到字符串并显示
由于上篇文章说过NDK怎么建立工程 添加native方法等 以后的文章只会给出相关代码,并不再做出相关解释
#include <jni.h>
#include <string.h>
JNIEXPORT jint JNICALL Java_com_example_dsassdada_MainActivity_add
(JNIEnv *env, jobject obj, jint a, jint b){
return a+b;
}
JNIEXPORT jstring JNICALL Java_com_example_dsassdada_MainActivity_result
(JNIEnv *env, jobject obj, jstring str){
char * c;
//载入java/lang/String类
jclass clzz = (*env)->FindClass(env,"java/lang/String");
jstring strencode = (*env)->NewStringUTF(env,"GB2312"); // 声明一个"GB2312"编码的java字符串
//得到方法ID (Ljava/lang/String;)[B)为getBytes方法的签名 如何得到下面会介绍
jmethodID method = (*env)->GetMethodID(env,clzz,"getBytes","(Ljava/lang/String;)[B");
//为什么strencode不直接换成"GB2312"因为这个参数是java方法
jbyteArray ja = (*env)->CallObjectMethod(env,str,method,strencode);
jsize length = (*env)->GetArrayLength(env,ja);
jbyte* jb = (*env)->GetByteArrayElements(env,ja,0);//得到一个指向ja的Java数组元素的C指针
if(length>0){
c = (char *)malloc(length+1);//多创建1个字节存放0,字符串结尾以\0为标志
memcpy(c,jb,length);
c[length] = 0;//到这地方Java中传进来的str字符串转换成了C语言中的字符串
}
(*env)->ReleaseByteArrayElements(env,ja,jb,0);//释放相关指针
return (*env)->NewStringUTF(env,c);//c是C语言中的字符串形式 用NewStringUTF转换为java形式并返回
}
得到方法签名
找到getBytes方法存在的java文件在电脑上的位置 E:\android-sdk-windows\sources\android-17\java\lang\String.java
打开cmd 执行 cd E:\android-sdk-windows\sources\android-17
下一步执行 javap -s java.lang.String 然后cmd会回显 如下:
public byte[] getBytes(java.lang.String) throws java.io.UnsupportedEncodingException;
descriptor: (Ljava/lang/String;)[B(Ljava/lang/String;)[B就是这个方法的签名