Skip to content

Commit

Permalink
More type safe background task parameters #85
Browse files Browse the repository at this point in the history
  • Loading branch information
mikaelsvensson committed Dec 11, 2014
1 parent 65a4f02 commit e584f46
Show file tree
Hide file tree
Showing 9 changed files with 83 additions and 41 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,8 @@ public RemoteActivityRepoImpl(Context ctx) {
mContext = ctx;
mBackgroundTasksListener = new BackgroundTasksHandlerThread.Listener() {
@Override
public BackgroundTasksHandlerThread.ListenerAction onDone(Object[] parameters, Object response, BackgroundTask task) {
if (task == BackgroundTask.READ_ACTIVITY) {
public BackgroundTasksHandlerThread.ListenerAction onDone(Object parameter, Object response, BackgroundTask task) {
if (task == BackgroundTask.READ_ACTIVITY && response instanceof List) {
List<ActivityBean> activities = (List<ActivityBean>) response;
LogUtil.d(RemoteActivityRepoImpl.class.getName(), activities.size() + " activities have been read.");
for (Activity activity : activities) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ public class BackgroundTasksHandlerThread extends HandlerThread {
private int taskCount;
private List<Listener> mListeners = new ArrayList<Listener>();

public static interface BackgroundTaskExecutor {
Object run(Object[] params, Context context);
public static interface BackgroundTaskExecutor<R, P> {
R run(P param, Context context);
}


Expand All @@ -40,7 +40,7 @@ public void postReponse(Runnable runnable) {
}

public interface Listener {
ListenerAction onDone(Object[] parameters, Object response, BackgroundTask task);
ListenerAction onDone(Object parameter, Object response, BackgroundTask task);
}

public enum ListenerAction {
Expand All @@ -66,10 +66,10 @@ protected synchronized void onLooperPrepared() {
}
}

private Map<Integer, Object[]> mTaskParameters = Collections.synchronizedMap(new HashMap<Integer, Object[]>());
private Map<Integer, Object> mTaskParameters = Collections.synchronizedMap(new HashMap<Integer, Object>());

public void queueSetFavourites() {
queueTask(BackgroundTask.SET_FAVOURITES);
queueTask(BackgroundTask.SET_FAVOURITES, null);
}

public synchronized void queueReadActivity(final ActivityKey activityKey, final RemoteActivityRepoImpl remoteActivityRepo) {
Expand All @@ -79,18 +79,18 @@ public synchronized void queueReadActivity(final ActivityKey activityKey, final
}

public void queueCleanCache() {
queueTask(BackgroundTask.CLEAN_CACHE);
queueTask(BackgroundTask.CLEAN_CACHE, null);
}

public void queueGetMediaResource(ImageView imageView, URI[] uris, int maxFileSize) {
LogUtil.d(BackgroundTasksHandlerThread.class.getName(), "Wants to display one of " + uris + " in an image view.");
queueTask(BackgroundTask.DISPLAY_IMAGE, imageView, uris, Integer.valueOf(maxFileSize));
queueTask(BackgroundTask.DISPLAY_IMAGE, new DisplayImageTaskParam(imageView, Integer.valueOf(maxFileSize), uris));
}

private synchronized void queueTask(BackgroundTask task, Object... parameters) {
private synchronized void queueTask(BackgroundTask task, Object parameter) {
if (!isClosed()) {
taskCount++;
mTaskParameters.put(taskCount, parameters);
mTaskParameters.put(taskCount, parameter);
if (mHandler == null) {
LogUtil.d(BackgroundTasksHandlerThread.class.getName(), "Handler not yet initialised");
mPendingTasks.put(taskCount, task);
Expand Down Expand Up @@ -129,7 +129,7 @@ public synchronized void removeListener(Listener listener) {
}
}

private synchronized void fireOnDone(Object[] parameters, Object response, BackgroundTask task) {
private synchronized void fireOnDone(Object parameters, Object response, BackgroundTask task) {
// LogUtil.d(BackgroundTasksHandlerThread.class.getName(), "Number of listeners: " + mListeners.size());
if (!isClosed()) {

Expand All @@ -147,7 +147,7 @@ private class MessageHandler extends Handler {

@Override
public void handleMessage(final Message msg) {
final Object[] parameters;
final Object parameters;
Object obj = msg.obj;
final BackgroundTask task = BackgroundTask.values()[msg.what];
// LogUtil.d(BackgroundTasksHandlerThread.class.getName(), "Background task " + obj + ": " + task.name() + " STARTED");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import java.util.Arrays;
import java.util.Comparator;

public class CleanImageCacheTaskExecutor extends ImageCacheTaskExecutor {
public class CleanImageCacheTaskExecutor extends ImageCacheTaskExecutor<Void, Void> {

private static final int MINIMUM_TIME_BETWEEN_CLEANUP = 5 * 60 * 1000; // 5 minutes
private static final Comparator<File> SORT_NEWEST_FIRST = new Comparator<File>() {
Expand All @@ -33,7 +33,7 @@ public CleanImageCacheTaskExecutor(int cacheSizeLimit, int minimumTimeBetweenCle
}

@Override
public Object run(Object[] params, Context context) {
public Void run(Void param, Context context) {
if (System.currentTimeMillis() - lastRun < minimumTimeBetweenCleanup) {
LogUtil.d(CleanImageCacheTaskExecutor.class.getName(), "Will not purge image cache since it has been less than one minute since the last clean-up.");
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@
import java.util.HashMap;
import java.util.Map;

class DisplayImageTaskExecutor extends ImageCacheTaskExecutor {
class DisplayImageTaskExecutor extends ImageCacheTaskExecutor<Object, DisplayImageTaskParam> {
private Map<URI, Exception> blockedURLs = Collections.synchronizedMap(new HashMap<URI, Exception>());

@Override
public Object run(Object[] params, Context context) {
final URI[] uris = (URI[]) params[1];
int maxFileSize = params.length > 2 && params[2] != null && params[2] instanceof Integer ? (Integer) params[2] : 10000;
public Object run(DisplayImageTaskParam param, Context context) {
final URI[] uris = param.getURIs();
int maxFileSize = param.getMaxFileSize() > 0 ? param.getMaxFileSize() : 10000;
if (uris == null || uris.length == 0) {
LogUtil.e(BackgroundTasksHandlerThread.class.getName(), "Nothing to do. No URI for object.");
return null;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package se.devscout.android.util.concurrency;

import android.widget.ImageView;

import java.net.URI;

public class DisplayImageTaskParam {
private URI[] mURIs;
private int mMaxFileSize;
private ImageView mImageView;

public DisplayImageTaskParam(ImageView imageView, int maxFileSize, URI[] URIs) {
mImageView = imageView;
mMaxFileSize = maxFileSize;
mURIs = URIs;
}

public URI[] getURIs() {
return mURIs;
}

public void setURIs(URI[] URIs) {
mURIs = URIs;
}

public int getMaxFileSize() {
return mMaxFileSize;
}

public void setMaxFileSize(int maxFileSize) {
mMaxFileSize = maxFileSize;
}

public ImageView getImageView() {
return mImageView;
}

public void setImageView(ImageView imageView) {
mImageView = imageView;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public abstract class ImageCacheTaskExecutor implements BackgroundTasksHandlerThread.BackgroundTaskExecutor {
public abstract class ImageCacheTaskExecutor<R, P> implements BackgroundTasksHandlerThread.BackgroundTaskExecutor<R, P> {
protected static final String IMAGE_CACHE_FILENAME_PREFIX = "image-cache-";

protected File getCacheFile(URI uri, Context context) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
package se.devscout.android.util.concurrency;

import android.content.Context;
import se.devscout.android.model.ActivityBean;
import se.devscout.android.model.repo.remote.RemoteActivityRepoImpl;
import se.devscout.android.util.LogUtil;
import se.devscout.android.util.http.UnauthorizedException;
import se.devscout.server.api.model.ActivityKey;

public class ReadActivitiesTaskExecutor implements BackgroundTasksHandlerThread.BackgroundTaskExecutor {
import java.util.List;

public class ReadActivitiesTaskExecutor implements BackgroundTasksHandlerThread.BackgroundTaskExecutor<List<ActivityBean>, RemoteActivityRepoImpl> {
@Override
public Object run(Object[] params, Context context) {
RemoteActivityRepoImpl remoteActivityRepo = (RemoteActivityRepoImpl) params[0];
public List<ActivityBean> run(RemoteActivityRepoImpl param, Context context) {
RemoteActivityRepoImpl remoteActivityRepo = param;

try {
ActivityKey[] keys = remoteActivityRepo.getPendingActivityReadRequests();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
package se.devscout.android.util.concurrency;

import android.content.Context;
import android.graphics.Bitmap;
import se.devscout.android.model.repo.remote.RemoteActivityRepoImpl;
import se.devscout.android.util.LogUtil;
import se.devscout.android.util.http.UnauthorizedException;
import se.devscout.android.util.http.UnhandledHttpResponseCodeException;

import java.io.IOException;

class SetFavouritesTaskExecutor implements BackgroundTasksHandlerThread.BackgroundTaskExecutor {
class SetFavouritesTaskExecutor implements BackgroundTasksHandlerThread.BackgroundTaskExecutor<Void, Void> {
@Override
public Bitmap run(Object[] params, Context context) {
public Void run(Void param, Context context) {
try {
RemoteActivityRepoImpl.getInstance(context).sendSetFavouritesRequest();
} catch (IOException e) {
Expand Down
29 changes: 14 additions & 15 deletions src/se/devscout/android/view/AsyncImageView.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import se.devscout.android.util.LogUtil;
import se.devscout.android.util.concurrency.BackgroundTask;
import se.devscout.android.util.concurrency.BackgroundTasksHandlerThread;
import se.devscout.android.util.concurrency.DisplayImageTaskParam;
import se.devscout.android.util.http.ContentTooLongException;

import java.net.URI;
Expand Down Expand Up @@ -88,23 +89,21 @@ protected void onInitImage(AsyncImageBean properties) {
private BackgroundTasksHandlerThread.Listener createTaskListener(final URI[] requestedURIs) {
return new BackgroundTasksHandlerThread.Listener() {
@Override
public BackgroundTasksHandlerThread.ListenerAction onDone(Object[] parameters, Object response, BackgroundTask task) {
if (task == BackgroundTask.DISPLAY_IMAGE) {
boolean isImageViewAndURIReturned = parameters[0] instanceof ImageView && parameters[1] instanceof URI[];
if (isImageViewAndURIReturned) {
ImageView imageView = (ImageView) parameters[0];
URI[] eventURIs = (URI[]) parameters[1];
if (Arrays.equals(eventURIs, (URI[]) imageView.getTag(R.id.imageViewUri))) {
if (response instanceof Bitmap) {
onBitmapResponse((Bitmap) response, imageView);
} else if (response instanceof Exception) {
onExceptionResponse((Exception) response, imageView);
}
} else {
LogUtil.d(AsyncImageView.class.getName(), "Image has been loaded but the image view has been recycled and is now used for another image.");
public BackgroundTasksHandlerThread.ListenerAction onDone(Object parameter, Object response, BackgroundTask task) {
if (task == BackgroundTask.DISPLAY_IMAGE && parameter instanceof DisplayImageTaskParam) {
DisplayImageTaskParam displayImageTaskParam = (DisplayImageTaskParam) parameter;
ImageView imageView = displayImageTaskParam.getImageView();
URI[] eventURIs = displayImageTaskParam.getURIs();
if (Arrays.equals(eventURIs, (URI[]) imageView.getTag(R.id.imageViewUri))) {
if (response instanceof Bitmap) {
onBitmapResponse((Bitmap) response, imageView);
} else if (response instanceof Exception) {
onExceptionResponse((Exception) response, imageView);
}
return Arrays.equals(requestedURIs, eventURIs) ? BackgroundTasksHandlerThread.ListenerAction.REMOVE : BackgroundTasksHandlerThread.ListenerAction.KEEP;
} else {
LogUtil.d(AsyncImageView.class.getName(), "Image has been loaded but the image view has been recycled and is now used for another image.");
}
return Arrays.equals(requestedURIs, eventURIs) ? BackgroundTasksHandlerThread.ListenerAction.REMOVE : BackgroundTasksHandlerThread.ListenerAction.KEEP;
}
return BackgroundTasksHandlerThread.ListenerAction.KEEP;
}
Expand Down

0 comments on commit e584f46

Please sign in to comment.