简体   繁体   中英

not valid JNI reference using NewGlobalReference in android

Because of limited android application memory heap I am trying to create by cache array of bitmaps in C using malloc and memcpy.

So in java side I have:

private static native Bitmap getJNIBitmap(int id);
private static native void setJNIBitmap(int id, Bitmap bmp);

to send bitmap to C:

Bitmap bmp = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
setJNIBitmap(id, bmp);

to retrieve it from C:

Bitmap bitmap = getJNIBitmap(id);

In C code I have an array which I want to use a cache of bitmaps:

jobject bitmap_array[100];

To save bitmap in CI use:

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]);
}

To retrieve bitmap from C:

JNIEXPORT jobject JNICALL Java_droid_demo_ReadingActivity_getJNIBitmap(JNIEnv * env, jobject obj, jint id) {

  jobject temp = bitmap_array[(int)id];

  return temp;
}

I am green at using JNI and C in general, but in my head this should work. Well it doesn't and I receive:

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

Any ideas on why I cannot make bitmap_array[(int)id] a global reference? And maybe even how to solve this problem?

jobject only looks like a C pointer. In reality it is an opaque handle to some information inside the Java virtual machine. It is possible to copy pixel data from Java bitmap objects to native C arrays, but only through special APIs. It is also possible to create Java objects from native C code using JNI functions, but neither by simply casting between the two.

Trying to make a global ref out of something that isn't a Java reference in the first place doesn't even begin to make sense. You aren't doing anything with the result of NewGlobalRef(), which makes calling it pretty pointless, but if you want to make a global reference out of the jniBmp, pass that to NewGlobalRef() and store the result in your array. And copying the content of the jobject doesn't copy the bitmap data in the first place.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM