0

I'm trying to implement Android-wheel, a library that I can use to imitate a slot machine.

The demo project works fine, it use's android's own drawables => android.R.drawable.*

However when I change the default images to the ones I want it gives me this error :

java.lang.IllegalArgumentException: Cannot draw recycled bitmaps

All I changed was the id's array which contains the reference to the images

from

 private final int items[] = new int[] {
                android.R.drawable.star_big_on,
                android.R.drawable.stat_sys_warning,
                android.R.drawable.radiobutton_on_background,
                android.R.drawable.ic_delete
        };

to

private final int items[] = new int[] {
                R.drawable.sunglasses, R.drawable.ball, R.drawable.box};

Here's the rest of the code.

private class SlotMachineAdapter extends AbstractWheelAdapter {
        // Image size
        final int IMAGE_WIDTH = 267;
        final int IMAGE_HEIGHT = 200;

        // Slot machine symbols
        private final int items[] = new int[] {
                R.drawable.sunglasses, R.drawable.ball, R.drawable.box};

        // Cached images
        private List<SoftReference<Bitmap>> images;

        // Layout inflater
        private Context context;

        /**
         * Constructor
         */
        public SlotMachineAdapter(Context context) {
            this.context = context;
            images = new ArrayList<SoftReference<Bitmap>>(items.length);
            for (int id : items) {
                images.add(new SoftReference<Bitmap>(loadImage(id)));
            }
        }

        /**
         * Loads image from resources
         */
         private Bitmap loadImage(int id) {
        Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), id);
        Bitmap scaled = Bitmap.createScaledBitmap(bitmap, IMAGE_WIDTH, IMAGE_HEIGHT, true);
        bitmap.recycle();
        return scaled;
    }

        @Override
        public int getItemsCount() {
            return items.length;
        }

        // Layout params for image view
        final LayoutParams params = new LayoutParams(IMAGE_WIDTH, IMAGE_HEIGHT);

        @Override
        public View getItem(int index, View cachedView, ViewGroup parent) {
            ImageView img;
            if (cachedView != null) {
                img = (ImageView) cachedView;
            } else {
                img = new ImageView(context);
            }
            img.setLayoutParams(params);
            SoftReference<Bitmap> bitmapRef = images.get(index);
            Bitmap bitmap = bitmapRef.get();
            if (bitmap == null) {
                bitmap = loadImage(items[index]);
                images.set(index, new SoftReference<Bitmap>(bitmap));
            }
            img.setImageBitmap(bitmap);

            return img;
        }
    }

Here's the full stacktrace

    java.lang.IllegalArgumentException: Cannot draw recycled bitmaps
    at android.view.GLES20Canvas.drawBitmap(GLES20Canvas.java:778)
    at android.view.GLES20RecordingCanvas.drawBitmap(GLES20RecordingCanvas.java:117)
    at android.graphics.drawable.BitmapDrawable.draw(BitmapDrawable.java:393)
    at android.widget.ImageView.onDraw(ImageView.java:961)
    at android.view.View.draw(View.java:13765)
    at android.view.View.draw(View.java:13649)
    at android.view.ViewGroup.drawChild(ViewGroup.java:2940)
    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2810)
    at android.view.View.draw(View.java:13768)
    at kankan.wheel.widget.WheelView.drawItems(WheelView.java:587)
    at kankan.wheel.widget.WheelView.onDraw(WheelView.java:557)
    android.view.View.draw(View.java:13765)
    at android.view.View.getDisplayList(View.java:12716)
    at android.view.View.getDisplayList(View.java:12760)
    at android.view.View.draw(View.java:13489)
    at android.view.ViewGroup.drawChild(ViewGroup.java:2940)
    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2810)
    at android.view.View.getDisplayList(View.java:12714)
    at android.view.View.getDisplayList(View.java:12760)
    at android.view.View.draw(View.java:13489)
    at android.view.ViewGroup.drawChild(ViewGroup.java:2940)
    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2810)
    at android.view.View.draw(View.java:13768)
    at android.view.View.getDisplayList(View.java:12716)
    at android.view.View.getDisplayList(View.java:12760)
    at android.view.View.draw(View.java:13489)
    at android.view.ViewGroup.drawChild(ViewGroup.java:2940)
    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2810)
    at android.view.View.getDisplayList(View.java:12714)
    at android.view.View.getDisplayList(View.java:12760)
    at android.view.View.draw(View.java:13489)
    at android.view.ViewGroup.drawChild(ViewGroup.java:2940)
    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2810)
    at android.view.View.getDisplayList(View.java:12714)
    at android.view.View.getDisplayList(View.java:12760)
    at android.view.View.draw(View.java:13489)
    at android.view.ViewGroup.drawChild(ViewGroup.java:2940)
    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2810)
    at android.view.View.draw(View.java:13768)
    at android.widget.FrameLayout.draw(FrameLayout.java:467)
    at com.android.internal.policy.impl.PhoneWindow$DecorView.draw(PhoneWindow.java:2394)
    at android.view.View.getDisplayList(View.java:12716)
    at android.view.View.getDisplayList(View.java:12760)
    at android.view.HardwareRenderer$GlRenderer.draw(HardwareRenderer.java:1144)
    at android.view.ViewRootImpl.draw(ViewRootImpl.java:2267)
    at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:2139)
    at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1950)
    at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1107)
    at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:4464)
    at android.view.Choreographer$CallbackRecord.run(Choreographer.java:725)
    at android.view.Choreographer.doCallbacks(Choreographer.java:555)
    at android.view.Choreographer.doFrame(Choreographer.java:525)
    at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:711)
    at android.os.Handler.handleCallback(Handler.java:615)
    at android.os.Handler.dispatchMessage(Handler.java:92)
    at android.os.Looper.loop(Looper.java:137)

at android.app.ActivityThread.main(ActivityThread.java:4895) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:511) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:994) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:761) at dalvik.system.NativeStart.main(Native Method)
Mike Bryant
  • 2,455
  • 9
  • 39
  • 60

2 Answers2

1

I think it is beacause you do bitmap.recycle() too frequently,while the system.gc() is not timely called,so variable bitmap is recycle(), but not really cleared by the system, we can't use it to load the new image. so, just comment bitmap.recycle(),Let the system recycle the gabage by itself.

charming
  • 11
  • 1
0

Try with this -

if(bitmap!=null)
   {
      bitmap.recycle();
      bitmap=null;
   }
T_V
  • 17,440
  • 6
  • 36
  • 48