调用静态方法
java层方法
public staticString setByteByNative(byte[] b){
String str = newString(b);Log.e("yzy","bytes from native is "+ str);bytesFromNative= b;returnstr;}
JNI调用代码
char* str = "helloworld ,nice to meet you";//调用java层的函数,给java层的byte[]数组赋值 public static void setByteByNative(byte[] b)jclassmainActivityClazz = env->FindClass("yzy/ndkdemo/MainActivity");//第三个参数是java的方法签名,获取方法如下,需要配置好JAVA_HOME和CLASSPATH,否则会报找不到类//NDKDemo\app\build\intermediates\classes\debug>javap -s yzy,ndkdemo.MainActivityjmethodIDsetByteByNativeMethodId= env->GetStaticMethodID(mainActivityClazz,"setByteByNative","([B)Ljava/lang/String;");//char*转换为jbyteArrayjbyteArraybytes = env->NewByteArray(strlen(str));env->SetByteArrayRegion(bytes,0,strlen(str),(jbyte*)str);//jbyte b1 = 0x49; //报错//因为java层的setByteByNative返回值是String,所以这里是CallStaticObjectMethodenv->CallStaticObjectMethod(mainActivityClazz,setByteByNativeMethodId,bytes);env->DeleteLocalRef(mainActivityClazz);// 小心最后一个参数,如果为0是会释放 str 所指向的内存的. 如果str刚好指向一个栈上的数组的话,// 这样可能在Release 版本中造成内存方面的随机错误.可以用JNI_COMMIT来避免.env->ReleaseByteArrayElements(bytes,(jbyte*)str,JNI_COMMIT);
需要注意的问题
javah javap的使用,需要配置CLASS_PATH JAVA_HOME环境变量
资源引用的Delete和Release
JNI_COMMIT的使用
调用实例方法
Java层方法
private String name = "yzy";
public void setName(String n){
name = n;
}
JNI层方法
jclass m_cls = env->FindClass("yzy/ndkdemo/MainActivity");
jmethodID m_mid = env->GetMethodID(m_cls, "", "()V");//使用空参数的构造函数构建实例对象
jfieldID m_fid_1 = env->GetFieldID(m_cls, "name", "Ljava/lang/String;");
jobject m_obj = env->NewObject(m_cls, m_mid);
jmethodID setNameMethodId = env->GetMethodID(m_cls, "setName", "(Ljava/lang/String;)V");//通过javap获取方法签名
if(setNameMethodId == NULL){
return;
}
jstring str2 = env->NewStringUTF("HelloWorld");
// env->CallObjectMethod(m_obj, setNameMethodId, str2);1.方法用错了
// env->CallVoidMethod(m_obj,setNameMethodId,"adfa"); 2.这个地方不能像java那样
env->CallVoidMethod(m_obj, setNameMethodId, str2);
jstring name = (jstring) env->GetObjectField(m_obj, m_fid_1);//通过对象属性的ID 获取对象的中该属性的值
// LOGV("==================%s", name); 3.这个报错,,,我擦!!!!那如何打印jstring字符串呢?
LOGV("==================%s", get_chars_from_jstring(env,name));
env->DeleteLocalRef(m_cls);
env->DeleteLocalRef(m_obj);
需要注意的问题
如何获取java实例对象的属性ID
Java和JNI数据传递只能用jstring,jbytearray等中间类型
jstring不能用LOGV打印,LOGV只能打印char*