由于android应用程序内存堆有限,我试图使用malloc和memcpy在C语言中使用位图缓存数组创建。
所以在java方面我有:
private static native Bitmap getJNIBitmap(int id);
private static native void setJNIBitmap(int id, Bitmap bmp);
将位图发送到C:
Bitmap bmp = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
setJNIBitmap(id, bmp);
从C:
中检索它Bitmap bitmap = getJNIBitmap(id);
在C代码中,我有一个数组,我想使用位图缓存:
jobject bitmap_array[100];
要在C中保存位图,请使用:
JNIEXPORT void JNICALL Java_droid_demo_ReadingActivity_setJNIBitmap(JNIEnv* env, jobject obj, jint id, jobject jniBmp) {
AndroidBitmapInfo info;
AndroidBitmap_getInfo(env, jniBmp, &info);
long byteSize = (info.stride * info.height)+16;
bitmap_array[(int)id] = (jobject *)malloc(byteSize);
memcpy(bitmap_array[(int)id], jniBmp, byteSize);
(*env)->NewGlobalRef(env, bitmap_array[(int)id]);
}
从C:
中检索位图JNIEXPORT jobject JNICALL Java_droid_demo_ReadingActivity_getJNIBitmap(JNIEnv * env, jobject obj, jint id) {
jobject temp = bitmap_array[(int)id];
return temp;
}
我很擅长使用JNI和C,但在我看来这应该有效。嗯,它没有,我收到:
10-05 10:35:54.890: W/dalvikvm(12493): JNI WARNING: 0x5d5e0008 is not a valid JNI reference
10-05 10:35:54.890: W/dalvikvm(12493): in Ldroid/demo/ReadingActivity;.setJNIBitmap:(ILandroid/graphics/Bitmap;)V (NewGlobalRef)
10-05 10:35:54.890: I/dalvikvm(12493): "main" prio=5 tid=1 RUNNABLE
10-05 10:35:54.890: I/dalvikvm(12493): | group="main" sCount=0 dsCount=0 obj=0x41611568 self=0x416019f8
10-05 10:35:54.890: I/dalvikvm(12493): | sysTid=12493 nice=0 sched=0/0 cgrp=apps handle=1074710320
10-05 10:35:54.890: I/dalvikvm(12493): | schedstat=( 7665497000 93442000 221 ) utm=418 stm=348 core=1
关于为什么我不能使bitmap_array [(int)id]成为全局引用的任何想法?甚至可能如何解决这个问题?
答案 0 :(得分:2)
jobject只看起来像C指针。实际上,它是Java虚拟机内部某些信息的不透明句柄。可以将像素数据从Java位图对象复制到本机C数组,但只能通过特殊的API。也可以使用JNI函数从本机C代码创建Java对象,但不能简单地在两者之间进行转换。
答案 1 :(得分:-1)
尝试从一开始就不是Java引用的全局引用开始甚至没有意义。你没有对NewGlobalRef()的结果做任何事情,这使得调用它毫无意义,但是如果你想从jniBmp中创建一个全局引用,那么将它传递给NewGlobalRef()并存储结果在你的数组中。并且复制作业的内容不会首先复制位图数据。