Android DialogFragment中的位图错误
我正在开发一个应用程序,它接收来自其他应用程序的事件(登录尝试),然后在对话框片段中显示登录过程的结果。登录是通过指纹识别完成的,因此在结果中我需要显示指纹图像(这是一个位图) 该对话框工作正常,我没有收到任何错误,但问题是:如果用户尝试快速登录,有时我在显示图像时会收到此错误:Android DialogFragment中的位图错误,android,bitmap,android-dialogfragment,recycle,Android,Bitmap,Android Dialogfragment,Recycle,我正在开发一个应用程序,它接收来自其他应用程序的事件(登录尝试),然后在对话框片段中显示登录过程的结果。登录是通过指纹识别完成的,因此在结果中我需要显示指纹图像(这是一个位图) 该对话框工作正常,我没有收到任何错误,但问题是:如果用户尝试快速登录,有时我在显示图像时会收到此错误: W/dalvikvm( 1830): threadid=1: thread exiting with uncaught exception (group=0x2bf4efc0) E/AndroidRuntime( 18
W/dalvikvm( 1830): threadid=1: thread exiting with uncaught exception (group=0x2bf4efc0)
E/AndroidRuntime( 1830): FATAL EXCEPTION: main
E/AndroidRuntime( 1830): java.lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap@2cd4a720
E/AndroidRuntime( 1830): at android.graphics.Canvas.throwIfRecycled(Canvas.java:1026)
E/AndroidRuntime( 1830): at android.graphics.Canvas.drawBitmap(Canvas.java:1127)
E/AndroidRuntime( 1830): at android.graphics.drawable.BitmapDrawable.draw(BitmapDrawable.java:393)
E/AndroidRuntime( 1830): at android.view.View.draw(View.java:13443)
E/AndroidRuntime( 1830): at android.view.View.draw(View.java:13342)
E/AndroidRuntime( 1830): at android.view.ViewGroup.drawChild(ViewGroup.java:2929)
E/AndroidRuntime( 1830): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2799)
E/AndroidRuntime( 1830): at android.view.View.draw(View.java:13461)
E/AndroidRuntime( 1830): at android.view.View.draw(View.java:13342)
E/AndroidRuntime( 1830): at android.view.ViewGroup.drawChild(ViewGroup.java:2929)
E/AndroidRuntime( 1830): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2799)
E/AndroidRuntime( 1830): at android.view.View.draw(View.java:13461)
E/AndroidRuntime( 1830): at android.view.View.draw(View.java:13342)
E/AndroidRuntime( 1830): at android.view.ViewGroup.drawChild(ViewGroup.java:2929)
E/AndroidRuntime( 1830): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2799)
E/AndroidRuntime( 1830): at android.view.View.draw(View.java:13340)
E/AndroidRuntime( 1830): at android.view.ViewGroup.drawChild(ViewGroup.java:2929)
E/AndroidRuntime( 1830): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2799)
E/AndroidRuntime( 1830): at android.view.View.draw(View.java:13340)
E/AndroidRuntime( 1830): at android.view.ViewGroup.drawChild(ViewGroup.java:2929)
E/AndroidRuntime( 1830): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2799)
E/AndroidRuntime( 1830): at android.view.View.draw(View.java:13461)
E/AndroidRuntime( 1830): at android.widget.FrameLayout.draw(FrameLayout.java:467)
E/AndroidRuntime( 1830): at com.android.internal.policy.impl.PhoneWindow$DecorView.draw(PhoneWindow.java:2188)
E/AndroidRuntime( 1830): at android.view.ViewRootImpl.drawSoftware(ViewRootImpl.java:2326)
E/AndroidRuntime( 1830): at android.view.ViewRootImpl.draw(ViewRootImpl.java:2221)
E/AndroidRuntime( 1830): at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:2089)
E/AndroidRuntime( 1830): at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1864)
E/AndroidRuntime( 1830): at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1032)
E/AndroidRuntime( 1830): at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:4282)
E/AndroidRuntime( 1830): at android.view.Choreographer$CallbackRecord.run(Choreographer.java:725)
E/AndroidRuntime( 1830): at android.view.Choreographer.doCallbacks(Choreographer.java:555)
E/AndroidRuntime( 1830): at android.view.Choreographer.doFrame(Choreographer.java:525)
E/AndroidRuntime( 1830): at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:711)
E/AndroidRuntime( 1830): at android.os.Handler.handleCallback(Handler.java:615)
E/AndroidRuntime( 1830): at android.os.Handler.dispatchMessage(Handler.java:92)
E/AndroidRuntime( 1830): at android.os.Looper.loop(Looper.java:137)
E/AndroidRuntime( 1830): at android.app.ActivityThread.main(ActivityThread.java:4745)
E/AndroidRuntime( 1830): at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime( 1830): at java.lang.reflect.Method.invoke(Method.java:511)
E/AndroidRuntime( 1830): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
E/AndroidRuntime( 1830): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
E/AndroidRuntime( 1830): at dalvik.system.NativeStart.main(Native Method)
我显示/回收图像的代码如下:
public class FingerprintSettableImage implements SettableResultImage {
private final FingerPrintImageModel image;
private static Object lock = new Object();
private static final String TAG = FingerprintSettableImage.class
.getCanonicalName();
private static Bitmap previousFPImage = null;
public FingerprintSettableImage(final FingerPrintImageModel image) {
this.image = image;
}
@SuppressLint("NewApi")
@Override
public void bindToView(final ImageView view) {
synchronized (lock) {
if (image == null) {
view.setImageResource(R.drawable.drw_login_finger);
} else {
final Bitmap aux = ImageHelper.renderCroppedGreyscaleBitmap(
image.image, image.width, image.height);
final int fpImageDisplayRule = FPReaderSettings
.getImageDisplayRules(view.getContext());
if (fpImageDisplayRule == FPReaderSettings.DISPLAY_FP_IMAGE_FOR_PUNCH_AND_ENROLLMENT) {
Drawable d = new BitmapDrawable(view.getContext()
.getResources(), aux);
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) {
view.setBackgroundDrawable(d);
} else {
view.setBackground(d);
}
} else {
view.setBackgroundResource(R.drawable.drw_login_default_finger_image);
}
view.setImageResource(R.drawable.drw_login_finger_transparent);
recycle();
previousFPImage = aux;
}
}
}
@Override
public void recycle() {
if (previousFPImage != null && !previousFPImage.isRecycled()) {
Log.d(TAG, "Recycling image " + previousFPImage.hashCode());
previousFPImage.recycle();
}
}
}
也许我犯了一些愚蠢的错误,但我找不到它,有人能看看出了什么问题吗?你能发布ImageHelper.RenderCroppedGreyscaleBramp吗?我在手机上,所以无法准确追踪错误,我知道,但我很确定你在代码中错误的位置回收了位图。调试代码并设置断点,在此处循环并创建位图
public class ImageHelper {
/**
* Using the array generate a Bitmap object
*
* @param yuvData
* @param width
* @param height
* @return
*/
public static Bitmap renderCroppedGreyscaleBitmap(byte[] yuvData,
final int width, final int height) {
int[] pixels = new int[width * height];
int inputOffset = 0;
for (int y = 0; y < height; y++) {
final int outputOffset = y * width;
for (int x = 0; x < width; x++) {
final int grey = yuvData[inputOffset + x] & 0xff;
pixels[outputOffset + x] = 0xFF000000 | (grey * 0x00010101);
}
inputOffset += width;
}
final Bitmap bitmap = Bitmap.createBitmap(width, height,
Bitmap.Config.RGB_565);
bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
yuvData = null;
pixels = null;
return bitmap;
}
}
@Override
public View onCreateView(final LayoutInflater inflater,
final ViewGroup container, final Bundle savedInstanceState) {
...
setResultImage();
...
}
private void setResultImage() {
FingerPrintImageModel fpImageModel = curLC.getFingerImage();
image = new FingerprintSettableImage(fpImageModel);
Log.d(TAG, "binding image" + aux.getTimestamp());
image.bindToView(imageFP1);
}