RuntimeException on widget that has a Bitmap

Problems with Canvas, OpenGL, etc...

RuntimeException on widget that has a Bitmap

Postby gskbyte » Mon Aug 23, 2010 11:58 pm

Hi,

my app has widgets that have an ImageView and a TextView. On the onUpdate() method of the WidgetProvider, I put a Bitmap inside the ImageView this way:

Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.widget_btn);
Bitmap bitmap2 = BitmapManager.setColor(bitmap, red, green, blue);
views.setImageViewBitmap(R.id.image, bitmap2);


setColor() method is this:

Code: Select all
public synchronized static Bitmap setColor(Bitmap org, float r, float g, float b)
    {
        sColorMatrix.setScale(r, g, b, 1);
        sColorPaint.setColorFilter(new ColorMatrixColorFilter(sColorMatrix));
        // RGB_565 is faster, but loses transparency
        Bitmap ret = Bitmap.createBitmap(org.getWidth(), org.getHeight(), Bitmap.Config.ARGB_8888);
        try{
            sColorCanvas.setBitmap(ret);
            //sColorCanvas.drawColor(Color.);
            sColorCanvas.drawBitmap(org, 0, 0, sColorPaint);
        } catch (Throwable t){
           
        }
       
        return ret;
    }


The problem is that sometimes the widget throws a RuntimeException because somebody has recycled the Bitmap, and I don't know what to do. Some suggestions?

This is the stacktrace:
Code: Select all
java.lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap@462605a8
       at android.graphics.Canvas.throwIfRecycled(Canvas.java:955)
       at android.graphics.Canvas.drawBitmap(Canvas.java:1044)
       at android.graphics.drawable.BitmapDrawable.draw(BitmapDrawable.java:323)
       at android.widget.ImageView.onDraw(ImageView.java:923)
       at android.view.View.draw(View.java:6739)
       at android.view.ViewGroup.drawChild(ViewGroup.java:1648)
       at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1375)
       at android.view.ViewGroup.drawChild(ViewGroup.java:1646)
       at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1375)
       at android.view.ViewGroup.drawChild(ViewGroup.java:1646)
       at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1375)
       at android.widget.AbsListView.dispatchDraw(AbsListView.java:1365)
       at android.widget.ListView.dispatchDraw(ListView.java:3046)
       at android.view.View.draw(View.java:6845)
       at android.widget.AbsListView.draw(AbsListView.java:2257)
       at android.view.ViewGroup.drawChild(ViewGroup.java:1648)
       at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1375)
       at android.view.ViewGroup.drawChild(ViewGroup.java:1646)
       at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1375)
       at android.view.View.draw(View.java:6742)
       at android.widget.FrameLayout.draw(FrameLayout.java:352)
       at android.view.ViewGroup.drawChild(ViewGroup.java:1648)
       at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1375)
       at android.view.ViewGroup.drawChild(ViewGroup.java:1646)
       at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1375)
       at android.view.ViewGroup.drawChild(ViewGroup.java:1646)
       at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1375)
       at android.view.ViewGroup.drawChild(ViewGroup.java:1646)
       at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1375)
       at android.view.ViewGroup.drawChild(ViewGroup.java:1646)
       at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1375)
       at android.view.View.draw(View.java:6742)
       at android.widget.FrameLayout.draw(FrameLayout.java:352)
       at android.view.ViewGroup.drawChild(ViewGroup.java:1648)
       at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1375)
       at android.view.View.draw(View.java:6742)
       at android.widget.FrameLayout.draw(FrameLayout.java:352)
       at com.android.internal.policy.impl.PhoneWindow$DecorView.draw(PhoneWindow.java:1872)
       at android.view.ViewRoot.draw(ViewRoot.java:1422)
       at android.view.ViewRoot.performTraversals(ViewRoot.java:1167)
       at android.view.ViewRoot.handleMessage(ViewRoot.java:1744)
       at android.os.Handler.dispatchMessage(Handler.java:99)
       at android.os.Looper.loop(Looper.java:144)
       at android.app.ActivityThread.main(ActivityThread.java:4937)
       at java.lang.reflect.Method.invokeNative(Native Method)
       at java.lang.reflect.Method.invoke(Method.java:521)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
       at dalvik.system.NativeStart.main(Native Method)


Thank you!
gskbyte
Experienced Developer
Experienced Developer
 
Posts: 52
Joined: Tue Jan 12, 2010 1:51 pm

Top

Re: RuntimeException on widget that has a Bitmap

Postby mark@project8games.com » Tue Aug 24, 2010 3:04 am

Can't really tell without the full source, but my first thought was to start by moving "bitmap" and "bitmap2" from method scope to member scope and try from there.
User avatar
mark@project8games.com
Developer
Developer
 
Posts: 41
Joined: Tue Mar 02, 2010 8:33 pm

Re: RuntimeException on widget that has a Bitmap

Postby gskbyte » Tue Aug 24, 2010 2:07 pm

Hi, thank you for your help :)

I use this code on onUpdate():

Code: Select all
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds)
    {
        final int N = appWidgetIds.length;
       
        for (int i = 0; i < N; i++) {
            int id = appWidgetIds[i];
           
            Widget w = Manager.instance().get(context.getContentResolver(), id);
           
            log("onUpdate" + id);
            if(w!=null){
                updateAppWidget(context, appWidgetManager, id, w);
            } else {
                /* The program should not enter here*/
            }
        }
    }


Which calls the static method updateAppWidget, shown in the first post:

Code: Select all
public static void updateAppWidget(Context context, AppWidgetManager manager, int id, Widget w)
    {
        final RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget);
        views.setTextViewText(R.id.text, w.name);
       
        Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.widget_btn);
        Bitmap bitmap2 = BitmapManager.setColor(bitmap, w.color);
        //bitmap.recycle();
        sBitmaps.put(id, bitmap2);
        views.setImageViewBitmap(R.id.image, sBitmaps.get(id));
        views.setOnClickPendingIntent(R.id.image, getPendingIntent(context, id, w.filename));

        manager.updateAppWidget(id, views);
        log("staticUpdate " + id + " " + w.name);
    }


I have tested what you suggested using a static Array with the bitmaps, but the problem is still there. Thank you for your help :)

BTW I have visited your webpage and it looks very interesting, good job :)
gskbyte
Experienced Developer
Experienced Developer
 
Posts: 52
Joined: Tue Jan 12, 2010 1:51 pm

Top

Return to Android 2D/3D Graphics - OpenGL Problems

Who is online

Users browsing this forum: No registered users and 3 guests