OSDN Git Service

Fix 6341866 ANR in com.google.android.gallery3d due to com.android.gallery3d.ui.TileI...
authorRay Chen <raychen@google.com>
Wed, 2 May 2012 07:31:38 +0000 (15:31 +0800)
committerRay Chen <raychen@google.com>
Wed, 2 May 2012 07:31:38 +0000 (15:31 +0800)
RegionDecoder is run in a lower priority thread but it uses the same lock as setScreenNail while decoding, so a priority inversion causes this ANR.
The change tries to separate the lock so setScreenNail doesn't have to wait on the decoding process so the ANR could be avoided.

Change-Id: I02cc26fa0535adaa57cdcf94b819970e179311d1
b:6341866

src/com/android/gallery3d/ui/TileImageViewAdapter.java

index f4c6e65..0400de6 100644 (file)
@@ -100,10 +100,8 @@ public class TileImageViewAdapter implements TileImageView.Model {
     }
 
     @Override
-    public synchronized Bitmap getTile(int level, int x, int y, int tileSize,
+    public Bitmap getTile(int level, int x, int y, int tileSize,
             int borderSize) {
-        if (mRegionDecoder == null) return null;
-
         // wantRegion is the rectangle on the original image we want. askRegion
         // is the rectangle on the original image that we will ask from
         // mRegionDecoder. Both are in the coordinates of the original image,
@@ -115,8 +113,14 @@ public class TileImageViewAdapter implements TileImageView.Model {
         wantRegion.set(x - b, y - b, x + (tileSize << level) + b,
                 y + (tileSize << level) + b);
 
-        // askRegion is the intersection of wantRegion and the original image.
-        askRegion.set(0, 0, mImageWidth, mImageHeight);
+        BitmapRegionDecoder regionDecoder = null;
+        synchronized (this) {
+            regionDecoder = mRegionDecoder;
+            if (regionDecoder == null) return null;
+            // askRegion is the intersection of wantRegion and the original image.
+            askRegion.set(0, 0, mImageWidth, mImageHeight);
+        }
+
         Utils.assertTrue(askRegion.intersect(wantRegion));
 
         BitmapFactory.Options options = new BitmapFactory.Options();
@@ -127,8 +131,8 @@ public class TileImageViewAdapter implements TileImageView.Model {
         Bitmap bitmap;
 
         // In CropImage, we may call the decodeRegion() concurrently.
-        synchronized (mRegionDecoder) {
-            bitmap = mRegionDecoder.decodeRegion(askRegion, options);
+        synchronized (regionDecoder) {
+            bitmap = regionDecoder.decodeRegion(askRegion, options);
         }
 
         if (bitmap == null) {