Skip to content

Commit

Permalink
Issue photo#471
Browse files Browse the repository at this point in the history
- GalleryFragment.CustomImageFetcher,
SyncImageSelectionFragment.CustomImageFileSystemFetcher, ImageFetcher,
ImageFileSystemFetcher, ImageResizer: added new missing parameter
processingState to the overridden processBitmap method
- GalleryFragment.PhotosGridOnTouchListener: added additional check to
the onScale method to do not rebuild groups if new scal factor is the
same as previous
- GalleryFragment: added mRevalidateRequired field
- GalleryFragment: overrode setImageWorkerExitTaskEarly method and added
mAdapter.notifyDataSetChanged() call when the
setImageWorkerExitTaskEarly is called with false parameter and
previously it was called with true
- GalleryFragment: added mRevalidateRequired call to the refresh method
- DiskLruCache: changed modifier for the CACHE_FILENAME_PREFIX to public
- DiskLruCache: added getCacheDir - getter for the mCacheDire method
- ImageFetcher: added processingState parameter to the processBitmap
method variations
- ImageFetcher: added processingState parameter to the downloadBitmap
which is checked during download and may interrupt process
- ImageFetcher: added temp file usage for download and then renaming it
to target cache file to avoid problems in multithreading environment
- ImageWorker: added additional debug logging to the setExitTaskEarly
method
- ImageWorker: fixed debug logging in the cancelPotentialWork method and
added bitmapWorkerTask.isCancelled() check to avoid reusage of cancelled
jobs
- ImageWorker.BitmapWorkerTask: now it implements ProcessingState
interface
- ImageWorker.BitmapWorkerTask: added additional required parameter to
the processBitmap call in the doInBackground method
- ImageWorker.BitmapWorkerTask: added isProcessingCancelled method
implementation
- ImageWorker.ProcessingState: added
- ImageFlowUtils: added debug output to the getView method
- ImageFlowUtils: added layoutParams check to the getSingleImageView
method
- AndroidManifest.xml: updated version code and name
  • Loading branch information
httpdispatch committed Nov 20, 2013
1 parent 2e9bbf9 commit 5208ce1
Show file tree
Hide file tree
Showing 9 changed files with 116 additions and 37 deletions.
4 changes: 2 additions & 2 deletions app/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.trovebox.android.app"
android:installLocation="auto"
android:versionCode="13"
android:versionName="2.2 dev" >
android:versionCode="14"
android:versionName="2.3" >

<uses-sdk
android:minSdkVersion="7"
Expand Down
31 changes: 23 additions & 8 deletions app/src/com/trovebox/android/app/GalleryFragment.java
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ public class GalleryFragment extends CommonRefreshableFragmentWithImageWorker
ViewTreeObserver.OnGlobalLayoutListener photosGridListener;
PhotosGridOnTouchListener mPhotosGridOnTouchListener;

boolean mRevalidateRequired = false;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Expand Down Expand Up @@ -122,6 +124,21 @@ public void onAttach(Activity activity)

}

@Override
public void setImageWorkerExitTaskEarly(boolean exitTaskEarly) {
super.setImageWorkerExitTaskEarly(exitTaskEarly);
if (exitTaskEarly) {
mRevalidateRequired = true;
} else {
if (mRevalidateRequired) {
mRevalidateRequired = false;
if (mAdapter != null) {
mAdapter.notifyDataSetChanged();
}
}
}
}

public Album getAlbum() {
return mAlbum;
}
Expand Down Expand Up @@ -151,6 +168,7 @@ public void refresh()

void refresh(View v)
{
mRevalidateRequired = false;
if (mTags == null && mAlbum == null)
{
Intent intent = getActivity().getIntent();
Expand Down Expand Up @@ -277,21 +295,18 @@ public CustomImageFetcher(Context context, LoadingControl loadingControl, int si

@SuppressWarnings("unchecked")
@Override
protected Bitmap processBitmap(Object data)
{
protected Bitmap processBitmap(Object data, ProcessingState processingState) {
FlowObjectToStringWrapper<Photo> fo = (FlowObjectToStringWrapper<Photo>) data;
Photo imageData = fo.getObject();
double ratio = imageData.getHeight() == 0 ? 1 : (float) imageData.getWidth()
/ (float) imageData.getHeight();
int height = imageHeight;
int width = (int) (height * ratio);
Bitmap result = null;
try
{
try {
imageData = PhotoUtils.validateUrlForSizeExistAndReturn(imageData, thumbSize);
result = super.processBitmap(fo.toString(), width, height);
} catch (Exception e)
{
result = super.processBitmap(fo.toString(), width, height, processingState);
} catch (Exception e) {
GuiUtils.noAlertError(TAG, e);
}
return result;
Expand Down Expand Up @@ -664,7 +679,7 @@ public void onScale(float scaleFactor, float focusX, float focusY) {
"LibraryListOnTouchListener.onScale: new scale: %.2f, new height: %d",
newScaleFactor, (int) (newScaleFactor * mImageThumbSize));

if (newScaleFactor >= 0.5f && newScaleFactor <= 5.f) {
if (newScaleFactor >= 0.5f && newScaleFactor <= 5.f && mScaleFactor != newScaleFactor) {
mScaleFactor = newScaleFactor;
// Don't let the object get too small or too large.
rebuildPhotosGrid();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -869,10 +869,9 @@ public CustomImageFileSystemFetcher(Context context,
}

@Override
protected Bitmap processBitmap(Object data)
{
protected Bitmap processBitmap(Object data, ProcessingState processingState) {
ImageData imageData = (ImageData) data;
return super.processBitmap(imageData.data);
return super.processBitmap(imageData.data, processingState);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
*/
public class DiskLruCache {
private static final String TAG = "DiskLruCache";
private static final String CACHE_FILENAME_PREFIX = "cache_";
public static final String CACHE_FILENAME_PREFIX = "cache_";
private static final int MAX_REMOVALS = 4;
private static final int INITIAL_CAPACITY = 32;
private static final float LOAD_FACTOR = 0.75f;
Expand Down Expand Up @@ -440,6 +440,10 @@ public String createFilePath(String key) {
return createFilePath(mCacheDir, key);
}

public File getCacheDir() {
return mCacheDir;
}

/**
* Sets the target compression format and quality for images written to the
* disk cache.
Expand Down
58 changes: 47 additions & 11 deletions app/src/com/trovebox/android/app/bitmapfun/util/ImageFetcher.java
Original file line number Diff line number Diff line change
Expand Up @@ -112,10 +112,12 @@ private void checkConnection(Context context) {
* AsyncTaskEx background thread.
*
* @param data The data to load the bitmap, in this case, a regular http URL
* @param processingState may be used to determine whether the processing is
* cancelled during long operations
* @return The downloaded and resized bitmap
*/
private Bitmap processBitmap(String data) {
return processBitmap(data, imageWidth, imageHeight);
private Bitmap processBitmap(String data, ProcessingState processingState) {
return processBitmap(data, imageWidth, imageHeight, processingState);
}

/**
Expand All @@ -125,15 +127,18 @@ private Bitmap processBitmap(String data) {
* @param data The data to load the bitmap, in this case, a regular http URL
* @param imageWidth
* @param imageHeight
* @param processingState may be used to determine whether the processing is
* cancelled during long operations
* @return The downloaded and resized bitmap
*/
protected Bitmap processBitmap(String data, int imageWidth, int imageHeight) {
protected Bitmap processBitmap(String data, int imageWidth, int imageHeight,
ProcessingState processingState) {
if (BuildConfig.DEBUG) {
Log.d(TAG, "processBitmap - " + data);
}

// Download a bitmap, write it to a file
final File f = downloadBitmap(mContext, data, mCheckLoggedIn);
final File f = downloadBitmap(mContext, data, mCheckLoggedIn, processingState);

if (f != null) {
try
Expand All @@ -151,8 +156,8 @@ protected Bitmap processBitmap(String data, int imageWidth, int imageHeight) {
}

@Override
protected Bitmap processBitmap(Object data) {
return processBitmap(String.valueOf(data));
protected Bitmap processBitmap(Object data, ProcessingState processingState) {
return processBitmap(String.valueOf(data), processingState);
}

/**
Expand All @@ -162,9 +167,12 @@ protected Bitmap processBitmap(Object data) {
* @param context The context to use
* @param urlString The URL to fetch
* @param checkLoggedIn whether to check user logged in condition
* @param processingState may be used to determine whether the processing is
* cancelled during long operations
* @return A File pointing to the fetched bitmap
*/
public static File downloadBitmap(Context context, String urlString, boolean checkLoggedIn) {
public static File downloadBitmap(Context context, String urlString, boolean checkLoggedIn,
ProcessingState processingState) {
final File cacheDir = DiskLruCache.getDiskCacheDir(context, HTTP_CACHE_DIR);

if (CommonUtils.TEST_CASE && urlString == null)
Expand Down Expand Up @@ -196,7 +204,9 @@ public static File downloadBitmap(Context context, String urlString, boolean che
return null;
}
}

if (processingState != null && processingState.isProcessingCancelled()) {
return null;
}
final File cacheFile = new File(cache.createFilePath(urlString));

if (cache.containsKey(urlString)) {
Expand Down Expand Up @@ -225,16 +235,42 @@ public static File downloadBitmap(Context context, String urlString, boolean che
long start = System.currentTimeMillis();
final URL url = new URL(urlString);
urlConnection = (HttpURLConnection) url.openConnection();
final InputStream in =
new BufferedInputStream(urlConnection.getInputStream(), Utils.IO_BUFFER_SIZE);
out = new BufferedOutputStream(new FileOutputStream(cacheFile), Utils.IO_BUFFER_SIZE);

final InputStream in = new BufferedInputStream(urlConnection.getInputStream(),
Utils.IO_BUFFER_SIZE);
File tempFile = File.createTempFile(DiskLruCache.CACHE_FILENAME_PREFIX + "udl"
+ cacheFile.getName(), null,
cache.getCacheDir());
out = new BufferedOutputStream(new FileOutputStream(tempFile), Utils.IO_BUFFER_SIZE);

int b;
while ((b = in.read()) != -1) {
out.write(b);
if (processingState != null && processingState.isProcessingCancelled()) {
CommonUtils.debug(TAG,
"downloadBitmap: processing is cancelled. Removing temp file %1$s",
tempFile.getAbsolutePath());
out.close();
out = null;
tempFile.delete();
return null;
}
}
TrackerUtils.trackDataLoadTiming(System.currentTimeMillis() - start, "downloadBitmap",
TAG);
if (!cacheFile.exists()) {
CommonUtils.debug(TAG,
"downloadBitmap: cache file %1$s doesn't exist, renaming downloaded data",
cacheFile.getAbsolutePath());
if (!tempFile.renameTo(cacheFile)) {
return null;
}
} else {
CommonUtils.debug(TAG,
"downloadBitmap: cache file %1$s exists, removing downloaded data",
cacheFile.getAbsolutePath());
tempFile.delete();
}
return cacheFile;

} catch (final IOException e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ public static Bitmap processBitmap(String fileName, int imageWidth, int imageHei
}

@Override
protected Bitmap processBitmap(Object data)
protected Bitmap processBitmap(Object data, ProcessingState processingState)
{
return processBitmap(String.valueOf(data));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ protected Bitmap processBitmap(int resId, int imageWidth, int imageHeight) {
}

@Override
protected Bitmap processBitmap(Object data) {
protected Bitmap processBitmap(Object data, ProcessingState processingState) {
return processBitmap(Integer.parseInt(String.valueOf(data)));
}

Expand Down
30 changes: 25 additions & 5 deletions app/src/com/trovebox/android/app/bitmapfun/util/ImageWorker.java
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,7 @@ public void setImageFadeIn(boolean fadeIn) {
}

public void setExitTasksEarly(boolean exitTasksEarly) {
CommonUtils.debug(TAG, "setExitTasksEarly: called for parameter %1$b", exitTasksEarly);
mExitTasksEarly = exitTasksEarly;
}

Expand All @@ -282,9 +283,12 @@ public void setExitTasksEarly(boolean exitTasksEarly) {
*
* @param data The data to identify which image to process, as provided by
* {@link ImageWorker#loadImage(Object, ImageView)}
* @param processingCancelledState may be used to determine whether the
* processing is cancelled during long operations
* @return The processed bitmap
*/
protected abstract Bitmap processBitmap(Object data);
protected abstract Bitmap processBitmap(Object data,
ProcessingState processingCancelledState);

public static void cancelWork(ImageView imageView) {
final BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask(imageView);
Expand All @@ -305,12 +309,13 @@ public static void cancelWork(ImageView imageView) {
public static boolean cancelPotentialWork(Object data, ImageView imageView) {
final BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask(imageView);

if (bitmapWorkerTask != null) {
if (bitmapWorkerTask != null && !bitmapWorkerTask.isCancelled()) {
final Object bitmapData = bitmapWorkerTask.data;
if (bitmapData == null || !bitmapData.equals(data)) {
bitmapWorkerTask.cancel(true);
if (BuildConfig.DEBUG) {
CommonUtils.debug(TAG, "cancelPotentialWork - cancelled work for " + data);
CommonUtils
.debug(TAG, "cancelPotentialWork - cancelled work for " + bitmapData);
}
} else {
// The same work is already in progress.
Expand Down Expand Up @@ -339,7 +344,8 @@ private static BitmapWorkerTask getBitmapWorkerTask(ImageView imageView) {
/**
* The actual AsyncTaskEx that will asynchronously process the image.
*/
private class BitmapWorkerTask extends AsyncTaskEx<Object, Void, Bitmap> {
private class BitmapWorkerTask extends AsyncTaskEx<Object, Void, Bitmap> implements
ProcessingState {
private Object data;
private final WeakReference<ImageView> imageViewReference;
LoadingControl loadingControl;
Expand Down Expand Up @@ -419,7 +425,7 @@ protected Bitmap doInBackground(Object... params) {
// process method (as implemented by a subclass)
if (bitmap == null && !isCancelled() && getAttachedImageView() != null
&& !mExitTasksEarly) {
bitmap = processBitmap(params[0]);
bitmap = processBitmap(params[0], this);
}

// If the bitmap was processed and the image cache is available,
Expand Down Expand Up @@ -476,6 +482,11 @@ private ImageView getAttachedImageView() {

return null;
}

@Override
public boolean isProcessingCancelled() {
return isCancelled() || mExitTasksEarly;
}
}

/**
Expand Down Expand Up @@ -567,6 +578,15 @@ public ImageWorkerAdapter getAdapter() {
return mImageWorkerAdapter;
}

/**
* An interface to handle processing cancelled state in the processBitmap
* method. Useful for long loading operations such as downloadBitmap in
* ImageFetcher
*/
public static interface ProcessingState {
boolean isProcessingCancelled();
}

/**
* A very simple adapter for use with ImageWorker class and subclasses.
*/
Expand Down
15 changes: 10 additions & 5 deletions app/src/com/trovebox/android/app/util/ImageFlowUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout.LayoutParams;

import com.trovebox.android.app.bitmapfun.util.ImageWorker;

Expand Down Expand Up @@ -313,6 +314,7 @@ public View getView(
int imageViewId,
Context context) {
ViewGroup view;
CommonUtils.debug(TAG, "getView: called for position %1$d", position);
if (convertView == null)
{ // if it's not recycled, instantiate and initialize
final LayoutInflater layoutInflater = (LayoutInflater)
Expand Down Expand Up @@ -433,17 +435,20 @@ protected View getSingleImageView(
int height = imageHeight;
int width = (int) (ratio * height) + extraWidth;

CommonUtils.debug(TAG, "Processing image: " + value
CommonUtils.debug(TAG, "getSingleImageView: processing image: " + value
+ "; Width: " + getWidth(value)
+ "; Height: " + getHeight(value)
+ "; Extra width: " + extraWidth
+ "; Req Width: " + width
+ "; Req Height: " + height);

LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
width + 2 * borderSize,
height + 2 * borderSize);
view.setLayoutParams(layoutParams);
width = width + 2 * borderSize;
height = height + 2 * borderSize;
LinearLayout.LayoutParams layoutParams = (LayoutParams) view.getLayoutParams();
if (layoutParams == null || layoutParams.width != width || layoutParams.height != height) {
layoutParams = new LinearLayout.LayoutParams(width, height);
view.setLayoutParams(layoutParams);
}

additionalSingleImageViewInit(view, value);
ImageView imageView = (ImageView) view.findViewById(imageViewId);
Expand Down

0 comments on commit 5208ce1

Please sign in to comment.