异常
背景 : 为了做个YUV格式的转换
报错提醒: JNI : pin count on array [对象地址] ([B) is now [数字]
当达到一定的程度,程序就Crash掉了
报错如下
11-04 10:55:16.631: E/dalvikvm(3833): Failed adding to JNI pinned array ref table (1024 entries)
11-04 10:55:16.631: I/dalvikvm(3833): "main" prio=5 tid=1 RUNNABLE
11-04 10:55:16.631: I/dalvikvm(3833): | group="main" sCount=0 dsCount=0 obj=0x419e7cd8 self=0x419d63c8
11-04 10:55:16.631: I/dalvikvm(3833): | sysTid=3833 nice=0 sched=0/0 cgrp=apps handle=1074176340
11-04 10:55:16.631: I/dalvikvm(3833): | state=R schedstat=( 1828552233 638214124 2555 ) utm=168 stm=14 core=2
11-04 10:55:16.631: I/dalvikvm(3833): at com.xinwei.sdc.media.rotate.NewRotate.transNV21ToNV12b(Native Method)
11-04 10:55:16.631: I/dalvikvm(3833): at com.example.niojni.MainActivity.test(MainActivity.java:78)
11-04 10:55:16.631: I/dalvikvm(3833): at com.example.niojni.MainActivity.access$1(MainActivity.java:60)
11-04 10:55:16.631: I/dalvikvm(3833): at com.example.niojni.MainActivity$2.onClick(MainActivity.java:50)
11-04 10:55:16.631: I/dalvikvm(3833): at android.view.View.performClick(View.java:4438)
11-04 10:55:16.631: I/dalvikvm(3833): at android.view.View$PerformClick.run(View.java:18427)
11-04 10:55:16.631: I/dalvikvm(3833): at android.os.Handler.handleCallback(Handler.java:733)
11-04 10:55:16.631: I/dalvikvm(3833): at android.os.Handler.dispatchMessage(Handler.java:95)
11-04 10:55:16.631: I/dalvikvm(3833): at android.os.Looper.loop(Looper.java:136)
11-04 10:55:16.631: I/dalvikvm(3833): at android.app.ActivityThread.main(ActivityThread.java:5120)
11-04 10:55:16.631: I/dalvikvm(3833): at java.lang.reflect.Method.invokeNative(Native Method)
11-04 10:55:16.631: I/dalvikvm(3833): at java.lang.reflect.Method.invoke(Method.java:515)
11-04 10:55:16.631: I/dalvikvm(3833): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:788)
11-04 10:55:16.631: I/dalvikvm(3833): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:604)
11-04 10:55:16.631: I/dalvikvm(3833): at dalvik.system.NativeStart.main(Native Method)
11-04 10:55:16.631: E/dalvikvm(3833): VM aborting
11-04 10:55:16.631: A/libc(3833): Fatal signal 6 (SIGABRT) at 0x00000ef9 (code=-6), thread 3833 (.example.niojni)
检查问题代码
JNIEXPORT jint JNICALL Java_com_xinwei_sdc_media_rotate_NewRotate_transNV21ToNV12b
(JNIEnv * env, jobject thiz, jbyteArray dst, jbooleanArray src)
{
clock_t start_t, end_t, total_t;
start_t = clock();
jbyte * srcp = (*env)->GetByteArrayElements(env, src, 0);
jbyte * dstp = (*env)->GetByteArrayElements(env, dst, 0);
//这个函数做了个复制memcpy,以及调换某些位置而已
transNV21ToNV12(_width, _height, dstp, srcp);
end_t = clock();
total_t = end_t - start_t;
LOGD("B transNV21ToNV12b() cost time : %ld", total_t);
}
修复Bug后的代码
JNIEXPORT jint JNICALL Java_com_xinwei_sdc_media_rotate_NewRotate_transNV21ToNV12b
(JNIEnv * env, jobject thiz, jbyteArray dst, jbooleanArray src)
{
clock_t start_t, end_t, total_t;
start_t = clock();
jbyte * srcp = (*env)->GetByteArrayElements(env, src, 0);
jbyte * dstp = (*env)->GetByteArrayElements(env, dst, 0);
transNV21ToNV12(_width, _height, dstp, srcp);
(*env)->ReleaseByteArrayElements(env, src, srcp, JNI_ABORT);
(*env)->ReleaseByteArrayElements(env, dst, dstp, 0);
end_t = clock();
total_t = end_t - start_t;
LOGD("B transNV21ToNV12b() cost time : %ld", total_t);
}
谨记
释放很重要
ReleaseByteArrayElements((JNIEnv *)env, (jbyteArray )src, (jbyte *)srcp, jnimode)
;
额外
jnimode有3个常用值,其中一个是0,另外两个如下:
#define JNI_COMMIT 1 /* copy content, do not free buffer */
#define JNI_ABORT 2 /* free buffer w/o copying back */