Skip to content

Commit 515f986

Browse files
committed
on onSaveInstanceState save bitmap to temp file on disk to be restored instead of saving the bitmap into parcel
1 parent 61fd441 commit 515f986

2 files changed

Lines changed: 48 additions & 41 deletions

File tree

cropper/src/main/java/com/theartofdev/edmodo/cropper/BitmapUtils.java

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,32 @@ private static void fixRectForAspectRatio(Rect rect, int aspectRatioX, int aspec
315315
}
316316
}
317317

318+
/**
319+
* Write given bitmap to a temp file.
320+
* If file already exists no-op as we already saved the file in this session.
321+
* Uses JPEG 95% compression.
322+
*
323+
* @param uri the uri to write the bitmap to, if null
324+
* @return the uri where the image was saved in, either the given uri or new pointing to temp file.
325+
*/
326+
static Uri writeTempStateStoreBitmap(Context context, Bitmap bitmap, Uri uri) {
327+
try {
328+
boolean needSave = true;
329+
if (uri == null) {
330+
uri = Uri.fromFile(File.createTempFile("aic_state_store_temp", ".jpg", context.getCacheDir()));
331+
} else if (new File(uri.getPath()).exists()) {
332+
needSave = false;
333+
}
334+
if (needSave) {
335+
writeBitmapToUri(context, bitmap, uri, Bitmap.CompressFormat.JPEG, 95);
336+
}
337+
return uri;
338+
} catch (Exception e) {
339+
Log.w("AIC", "Failed to write bitmap to temp file for image-cropper save instance state", e);
340+
return null;
341+
}
342+
}
343+
318344
/**
319345
* Write the given bitmap to the given uri using the given compression.
320346
*/

cropper/src/main/java/com/theartofdev/edmodo/cropper/CropImageView.java

Lines changed: 22 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,11 @@ public class CropImageView extends FrameLayout {
187187
*/
188188
private boolean mSizeChanged;
189189

190+
/**
191+
* Temp URI used to save bitmap image to disk to preserve for instance state in case cropped was set with bitmap
192+
*/
193+
private Uri mSaveInstanceStateBitmapUri;
194+
190195
/**
191196
* Task used to load bitmap async from UI thread
192197
*/
@@ -829,7 +834,7 @@ public void setOnCropImageCompleteListener(OnCropImageCompleteListener listener)
829834
*/
830835
public void setImageBitmap(Bitmap bitmap) {
831836
mCropOverlayView.setInitialCropWindowRect(null);
832-
setBitmap(bitmap);
837+
setBitmap(bitmap, 0, null, 1, 0);
833838
}
834839

835840
/**
@@ -865,7 +870,7 @@ public void setImageResource(int resId) {
865870
if (resId != 0) {
866871
mCropOverlayView.setInitialCropWindowRect(null);
867872
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), resId);
868-
setBitmap(bitmap, resId);
873+
setBitmap(bitmap, resId, null, 1, 0);
869874
}
870875
}
871876

@@ -1000,7 +1005,7 @@ void onSetImageUriAsyncComplete(BitmapLoadingWorkerTask.Result result) {
10001005

10011006
if (result.error == null) {
10021007
mInitialDegreesRotated = result.degreesRotated;
1003-
setBitmap(result.bitmap, result.uri, result.loadSampleSize, result.degreesRotated);
1008+
setBitmap(result.bitmap, 0, result.uri, result.loadSampleSize, result.degreesRotated);
10041009
}
10051010

10061011
OnSetImageUriCompleteListener listener = mOnSetImageUriCompleteListener;
@@ -1027,27 +1032,6 @@ void onImageCroppingAsyncComplete(BitmapCroppingWorkerTask.Result result) {
10271032
}
10281033
}
10291034

1030-
/**
1031-
* {@link #setBitmap(Bitmap, int, Uri, int, int)}}
1032-
*/
1033-
private void setBitmap(Bitmap bitmap) {
1034-
setBitmap(bitmap, 0, null, 1, 0);
1035-
}
1036-
1037-
/**
1038-
* {@link #setBitmap(Bitmap, int, Uri, int, int)}}
1039-
*/
1040-
private void setBitmap(Bitmap bitmap, int imageResource) {
1041-
setBitmap(bitmap, imageResource, null, 1, 0);
1042-
}
1043-
1044-
/**
1045-
* {@link #setBitmap(Bitmap, int, Uri, int, int)}}
1046-
*/
1047-
private void setBitmap(Bitmap bitmap, Uri imageUri, int loadSampleSize, int degreesRotated) {
1048-
setBitmap(bitmap, 0, imageUri, loadSampleSize, degreesRotated);
1049-
}
1050-
10511035
/**
10521036
* Set the given bitmap to be used in for cropping<br>
10531037
* Optionally clear full if the bitmap is new, or partial clear if the bitmap has been manipulated.
@@ -1098,6 +1082,7 @@ private void clearImageInt() {
10981082
mZoomOffsetX = 0;
10991083
mZoomOffsetY = 0;
11001084
mImageMatrix.reset();
1085+
mSaveInstanceStateBitmapUri = null;
11011086

11021087
mImageView.setImageBitmap(null);
11031088

@@ -1151,18 +1136,16 @@ public void startCropWorkerTask(int reqWidth, int reqHeight, RequestSizeOptions
11511136

11521137
@Override
11531138
public Parcelable onSaveInstanceState() {
1154-
if (mLoadedImageUri == null && mBitmap == null) {
1139+
if (mLoadedImageUri == null && mBitmap == null && mImageResource < 1) {
11551140
return super.onSaveInstanceState();
11561141
}
11571142

11581143
Bundle bundle = new Bundle();
1159-
bundle.putParcelable("instanceState", super.onSaveInstanceState());
1160-
bundle.putParcelable("LOADED_IMAGE_URI", mLoadedImageUri);
1161-
bundle.putInt("LOADED_IMAGE_RESOURCE", mImageResource);
1162-
if (mLoadedImageUri == null && mImageResource < 1) {
1163-
bundle.putParcelable("SET_BITMAP", mBitmap);
1144+
Uri imageUri = mLoadedImageUri;
1145+
if (imageUri == null && mImageResource < 1) {
1146+
mSaveInstanceStateBitmapUri = imageUri = BitmapUtils.writeTempStateStoreBitmap(getContext(), mBitmap, mSaveInstanceStateBitmapUri);
11641147
}
1165-
if (mLoadedImageUri != null && mBitmap != null) {
1148+
if (imageUri != null && mBitmap != null) {
11661149
String key = UUID.randomUUID().toString();
11671150
BitmapUtils.mStateBitmap = new Pair<>(key, new WeakReference<>(mBitmap));
11681151
bundle.putString("LOADED_IMAGE_STATE_BITMAP_KEY", key);
@@ -1173,6 +1156,9 @@ public Parcelable onSaveInstanceState() {
11731156
bundle.putParcelable("LOADING_IMAGE_URI", task.getUri());
11741157
}
11751158
}
1159+
bundle.putParcelable("instanceState", super.onSaveInstanceState());
1160+
bundle.putParcelable("LOADED_IMAGE_URI", imageUri);
1161+
bundle.putInt("LOADED_IMAGE_RESOURCE", mImageResource);
11761162
bundle.putInt("LOADED_SAMPLE_SIZE", mLoadedSampleSize);
11771163
bundle.putInt("DEGREES_ROTATED", mDegreesRotated);
11781164
bundle.putParcelable("INITIAL_CROP_RECT", mCropOverlayView.getInitialCropWindowRect());
@@ -1207,9 +1193,9 @@ public void onRestoreInstanceState(Parcelable state) {
12071193
if (key != null) {
12081194
Bitmap stateBitmap = BitmapUtils.mStateBitmap != null && BitmapUtils.mStateBitmap.first.equals(key)
12091195
? BitmapUtils.mStateBitmap.second.get() : null;
1196+
BitmapUtils.mStateBitmap = null;
12101197
if (stateBitmap != null && !stateBitmap.isRecycled()) {
1211-
BitmapUtils.mStateBitmap = null;
1212-
setBitmap(stateBitmap, uri, bundle.getInt("LOADED_SAMPLE_SIZE"), 0);
1198+
setBitmap(stateBitmap, 0, uri, bundle.getInt("LOADED_SAMPLE_SIZE"), 0);
12131199
}
12141200
}
12151201
if (mLoadedImageUri == null) {
@@ -1220,14 +1206,9 @@ public void onRestoreInstanceState(Parcelable state) {
12201206
if (resId > 0) {
12211207
setImageResource(resId);
12221208
} else {
1223-
Bitmap bitmap = bundle.getParcelable("SET_BITMAP");
1224-
if (bitmap != null) {
1225-
setBitmap(bitmap);
1226-
} else {
1227-
uri = bundle.getParcelable("LOADING_IMAGE_URI");
1228-
if (uri != null) {
1229-
setImageUriAsync(uri);
1230-
}
1209+
uri = bundle.getParcelable("LOADING_IMAGE_URI");
1210+
if (uri != null) {
1211+
setImageUriAsync(uri);
12311212
}
12321213
}
12331214
}

0 commit comments

Comments
 (0)