Titanium JIRA Archive
Appcelerator Community (AC)

[AC-2920] FC when recycling a "Bitmap.createScaledBitmap" with the same size os the original Bitmap

GitHub Issuen/a
TypeBug
Priorityn/a
StatusClosed
ResolutionFixed
Resolution Date2012-09-05T11:36:45.000+0000
Affected Version/sn/a
Fix Version/sn/a
ComponentsTitanium SDK & CLI
Labelsandroid, crash, defect, release-2.1.0, release-2.2.0
ReporterLĂșcio Fernando Maciel
AssigneeAnirudh Nagesh
Created2012-08-07T17:19:07.000+0000
Updated2016-03-08T07:47:54.000+0000

Description

Testing the BrazilJS conference App on Android, I caught a strange bug that only happens with a very specific configuration. We could only trigger the bug on a Galaxy Nexus running 4.1.1, but I don't really know which other devices/versions could be affected. The code which triggered the bug is available at https://github.com/Nyvra/App-BrazilJS/blob/70a4e0c78ef9cc4e126043ef266b00e3138b92b4/Resources/android/ui/WinTalk.coffee
rowSpeaker.add(Ti.UI.createImageView({
      left: "13dp",
      width: "30dp",
      height: "30dp",
      image: "/images/speakers/detail/" + speaker_obj.picture
    }));
This triggered a Force Close with the following backtrace: E/TiApplication( 6391): (main) [61,13021] Sending event: exception on thread: main msg:java.lang.IllegalArgumentException: Cannot draw recycled bitmaps; Titanium 2.1.0,2012/06/28 12:16,6e3cab6 E/TiApplication( 6391): java.lang.IllegalArgumentException: Cannot draw recycled bitmaps E/TiApplication( 6391): at android.view.GLES20Canvas.drawBitmap(GLES20Canvas.java:778) E/TiApplication( 6391): at android.view.GLES20RecordingCanvas.drawBitmap(GLES20RecordingCanvas.java:117) E/TiApplication( 6391): at android.graphics.drawable.BitmapDrawable.draw(BitmapDrawable.java:393) E/TiApplication( 6391): at android.widget.ImageView.onDraw(ImageView.java:961) E/TiApplication( 6391): at android.view.View.draw(View.java:13458) E/TiApplication( 6391): at android.view.View.getDisplayList(View.java:12409) E/TiApplication( 6391): at android.view.View.getDisplayList(View.java:12453) E/TiApplication( 6391): at android.view.View.draw(View.java:13182) E/TiApplication( 6391): at android.view.ViewGroup.drawChild(ViewGroup.java:2929) E/TiApplication( 6391): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2799) E/TiApplication( 6391): at android.view.View.getDisplayList(View.java:12407) E/TiApplication( 6391): at android.view.View.getDisplayList(View.java:12453) E/TiApplication( 6391): at android.view.View.draw(View.java:13182) E/TiApplication( 6391): at android.view.ViewGroup.drawChild(ViewGroup.java:2929) E/TiApplication( 6391): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2799) E/TiApplication( 6391): at org.appcelerator.titanium.view.TiCompositeLayout.dispatchDraw(TiCompositeLayout.java:655) The problem is that a recycled Bitmap is being used. Studying the Titanium source code I've found a situation where TiDrawableReference.java getBitmap() function is recycling the returned Bitmap. From the Android SDK documentation: public static Bitmap createScaledBitmap (Bitmap src, int dstWidth, int dstHeight, boolean filter) Creates a new bitmap, scaled from an existing bitmap, when possible. If the specified width and height are the same as the current width and height of the source btimap, the source bitmap is returned and no new bitmap is created. Returns The new scaled bitmap or the source bitmap if no scaling is required. getBitmap() calls
b = Bitmap.createScaledBitmap(bTemp, destWidth, destHeight, true);
So whenever the bTemp Bitmap has the same size as the scaled Bitmap, the Android framework will return the original Bitmap (bTemp in this case), and we will have both bTemp and b pointing to the same Bitmap. Later in this function is called
    if (bTemp != null) {
        bTemp.recycle();
        bTemp = null;
    }
    ...
    return b;
Which will recycle the bTemp bitmap, which is the same as b Bitmap which is returned in the function, causing the "Cannot draw recycled bitmaps" I've created a fix for this, and will send a pull request.

Comments

  1. Anirudh Nagesh 2012-09-05

    Hi Lucio, Thanks for the pull request. But this issue has been fixed in the latest 2.1.2GA and 2.2.0 CI build. It was an issue specific to Android JellyBean. Regards, Anirudh
  2. Anirudh Nagesh 2012-09-05

    Resolved in 2.1.2GA and 2.2.0 CI

JSON Source