-/* ownCloud Android client application
- * Copyright (C) 2012-2014 ownCloud Inc.
+/**
+ * ownCloud Android client application
+ *
+ * @author David A. Velasco
+ * Copyright (C) 2015 ownCloud Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2,
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.BitmapFactory.Options;
-import android.graphics.Matrix;
import android.graphics.Point;
-import android.media.ExifInterface;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.FragmentStatePagerAdapter;
import com.actionbarsherlock.view.MenuItem;
import com.owncloud.android.R;
import com.owncloud.android.datamodel.OCFile;
-import com.owncloud.android.datamodel.ThumbnailsCacheManager;
-import com.owncloud.android.datamodel.ThumbnailsCacheManager.ThumbnailGenerationTask;
import com.owncloud.android.files.FileMenuFilter;
import com.owncloud.android.lib.common.utils.Log_OC;
import com.owncloud.android.ui.dialog.ConfirmationDialogFragment;
import com.owncloud.android.ui.dialog.RemoveFileDialogFragment;
import com.owncloud.android.ui.fragment.FileFragment;
import com.owncloud.android.utils.BitmapUtils;
-import com.owncloud.android.utils.TouchImageViewCustom;
+import third_parties.michaelOrtiz.TouchImageViewCustom;
/**
* Trying to get an instance with NULL {@link OCFile} or ownCloud {@link Account} values will produce an {@link IllegalStateException}.
*
* If the {@link OCFile} passed is not downloaded, an {@link IllegalStateException} is generated on instantiation too.
- *
- * @author David A. Velasco
*/
public class PreviewImageFragment extends FileFragment {
private static final String TAG = PreviewImageFragment.class.getSimpleName();
private boolean mIgnoreFirstSavedState;
+
+ private LoadBitmapTask mLoadBitmapTask = null;
/**
public void onStart() {
super.onStart();
if (getFile() != null) {
- BitmapLoader bl = new BitmapLoader(mImageView, mMessageView, mProgressWheel);
- bl.execute(new String[]{getFile().getStoragePath()});
+ mLoadBitmapTask = new LoadBitmapTask(mImageView, mMessageView, mProgressWheel);
+ mLoadBitmapTask.execute(new String[]{getFile().getStoragePath()});
}
}
+ @Override
+ public void onStop() {
+ Log_OC.d(TAG, "onStop starts");
+ if (mLoadBitmapTask != null) {
+ mLoadBitmapTask.cancel(true);
+ mLoadBitmapTask = null;
+ }
+ super.onStop();
+ }
+
/**
* {@inheritDoc}
*/
if (mBitmap != null) {
mBitmap.recycle();
System.gc();
+ // putting this in onStop() is just the same; the fragment is always destroyed by the ViewPager
+ // when swipes further than the valid offset, and onStop() is never called before than that
}
super.onDestroy();
}
}
- private class BitmapLoader extends AsyncTask<String, Void, Bitmap> {
+ private class LoadBitmapTask extends AsyncTask<String, Void, Bitmap> {
/**
* Weak reference to the target {@link ImageView} where the bitmap will be loaded into.
*
* @param imageView Target {@link ImageView} where the bitmap will be loaded into.
*/
- public BitmapLoader(ImageViewCustom imageView, TextView messageView, ProgressBar progressWheel) {
+ public LoadBitmapTask(ImageViewCustom imageView, TextView messageView, ProgressBar progressWheel) {
mImageViewRef = new WeakReference<ImageViewCustom>(imageView);
mMessageViewRef = new WeakReference<TextView>(messageView);
mProgressWheelRef = new WeakReference<ProgressBar>(progressWheel);
Bitmap result = null;
if (params.length != 1) return result;
String storagePath = params[0];
+ InputStream is = null;
try {
+ if (isCancelled()) return result;
+
File picture = new File(storagePath);
if (picture != null) {
- //Decode file into a bitmap in real size for being able to make zoom on the image
- result = BitmapFactory.decodeStream(new FlushedInputStream
- (new BufferedInputStream(new FileInputStream(picture))));
+ // Decode file into a bitmap in real size for being able to make zoom on the image
+ is = new FlushedInputStream(new BufferedInputStream(new FileInputStream(picture)));
+ result = BitmapFactory.decodeStream(is);
}
+ if (isCancelled()) return result;
+
if (result == null) {
mErrorMessageId = R.string.preview_image_error_unknown_format;
Log_OC.e(TAG, "File could not be loaded as a bitmap: " + storagePath);
}
} catch (OutOfMemoryError e) {
- Log_OC.e(TAG, "Out of memory occured for file " + storagePath, e);
+ Log_OC.w(TAG, "Out of memory rendering file " + storagePath + " in full size; scaling down");
+ if (isCancelled()) return result;
+
// If out of memory error when loading or rotating image, try to load it scaled
result = loadScaledImage(storagePath);
} catch (NoSuchFieldError e) {
mErrorMessageId = R.string.common_error_unknown;
- Log_OC.e(TAG, "Error from access to unexisting field despite protection; file " + storagePath, e);
+ Log_OC.e(TAG, "Error from access to unexisting field despite protection; file "
+ + storagePath, e);
} catch (Throwable t) {
mErrorMessageId = R.string.common_error_unknown;
Log_OC.e(TAG, "Unexpected error loading " + getFile().getStoragePath(), t);
+ } finally {
+ if (is != null) {
+ try {
+ is.close();
+ } catch (IOException e) {
+ Log_OC.e(TAG, "Unexpected exception closing stream; trying to continue ", e);
+ }
+ }
}
return result;
}
@Override
+ protected void onCancelled(Bitmap result) {
+ if (result != null) {
+ result.recycle();
+ }
+ }
+
+ @Override
protected void onPostExecute(Bitmap result) {
hideProgressWheel();
if (result != null) {
} else {
showErrorMessage();
}
+ if (mBitmap != null && mBitmap != result) {
+ // unused bitmap, release it! (just in case)
+ result.recycle();
+ }
}
-
+
@SuppressLint("InlinedApi")
private void showLoadedImage(Bitmap result) {
if (mImageViewRef != null) {
final ImageViewCustom imageView = mImageViewRef.get();
if (imageView != null) {
- imageView.setBitmap(result);
imageView.setImageBitmap(result);
imageView.setVisibility(View.VISIBLE);
- mBitmap = result;
- } // else , silently finish, the fragment was destroyed
+ mBitmap = result; // needs to be kept for recycling when not useful
+ }
}
if (mMessageViewRef != null) {
final TextView messageView = mMessageViewRef.get();