3636public final class BitmapRegionDecoder {
3737 private int mNativeBitmapRegionDecoder ;
3838 private boolean mRecycled ;
39+ // ensures that the native decoder object exists and that only one decode can
40+ // occur at a time.
41+ private final Object mNativeLock = new Object ();
3942
4043 /**
4144 * Create a BitmapRegionDecoder from the specified byte array.
@@ -179,24 +182,30 @@ private BitmapRegionDecoder(int decoder) {
179182 * decoded.
180183 */
181184 public Bitmap decodeRegion (Rect rect , BitmapFactory .Options options ) {
182- checkRecycled ("decodeRegion called on recycled region decoder" );
183- if (rect .right <= 0 || rect .bottom <= 0 || rect .left >= getWidth ()
184- || rect .top >= getHeight ())
185- throw new IllegalArgumentException ("rectangle is outside the image" );
186- return nativeDecodeRegion (mNativeBitmapRegionDecoder , rect .left , rect .top ,
187- rect .right - rect .left , rect .bottom - rect .top , options );
185+ synchronized (mNativeLock ) {
186+ checkRecycled ("decodeRegion called on recycled region decoder" );
187+ if (rect .right <= 0 || rect .bottom <= 0 || rect .left >= getWidth ()
188+ || rect .top >= getHeight ())
189+ throw new IllegalArgumentException ("rectangle is outside the image" );
190+ return nativeDecodeRegion (mNativeBitmapRegionDecoder , rect .left , rect .top ,
191+ rect .right - rect .left , rect .bottom - rect .top , options );
192+ }
188193 }
189194
190195 /** Returns the original image's width */
191196 public int getWidth () {
192- checkRecycled ("getWidth called on recycled region decoder" );
193- return nativeGetWidth (mNativeBitmapRegionDecoder );
197+ synchronized (mNativeLock ) {
198+ checkRecycled ("getWidth called on recycled region decoder" );
199+ return nativeGetWidth (mNativeBitmapRegionDecoder );
200+ }
194201 }
195202
196203 /** Returns the original image's height */
197204 public int getHeight () {
198- checkRecycled ("getHeight called on recycled region decoder" );
199- return nativeGetHeight (mNativeBitmapRegionDecoder );
205+ synchronized (mNativeLock ) {
206+ checkRecycled ("getHeight called on recycled region decoder" );
207+ return nativeGetHeight (mNativeBitmapRegionDecoder );
208+ }
200209 }
201210
202211 /**
@@ -210,9 +219,11 @@ public int getHeight() {
210219 * memory when there are no more references to this region decoder.
211220 */
212221 public void recycle () {
213- if (!mRecycled ) {
214- nativeClean (mNativeBitmapRegionDecoder );
215- mRecycled = true ;
222+ synchronized (mNativeLock ) {
223+ if (!mRecycled ) {
224+ nativeClean (mNativeBitmapRegionDecoder );
225+ mRecycled = true ;
226+ }
216227 }
217228 }
218229
0 commit comments