diff --git a/src/se/devscout/android/controller/fragment/ActivityFragment.java b/src/se/devscout/android/controller/fragment/ActivityFragment.java index bf178fa..26aa442 100644 --- a/src/se/devscout/android/controller/fragment/ActivityFragment.java +++ b/src/se/devscout/android/controller/fragment/ActivityFragment.java @@ -29,6 +29,8 @@ public class ActivityFragment extends ActivityBankFragment/* implements Backgrou private ObjectIdentifierBean mActivityKey; public void onRead(Activity activityProperties, View view) { + view.findViewById(R.id.progressBar).setVisibility(View.INVISIBLE); + FragmentActivity context = getActivity(); if (view == null || context == null) { LogUtil.e(ActivityFragment.class.getName(), "Could not display activity information since view or context is null: view = " + view + " context = " + context); @@ -37,7 +39,6 @@ public void onRead(Activity activityProperties, View view) { context.invalidateOptionsMenu(); - view.findViewById(R.id.progressBar).setVisibility(View.INVISIBLE); String ages = activityProperties.getAges().toString(); String participantCount = activityProperties.getParticipants().toString(); diff --git a/src/se/devscout/android/model/repo/remote/RemoteActivityRepoImpl.java b/src/se/devscout/android/model/repo/remote/RemoteActivityRepoImpl.java index aabbc79..f324f7c 100644 --- a/src/se/devscout/android/model/repo/remote/RemoteActivityRepoImpl.java +++ b/src/se/devscout/android/model/repo/remote/RemoteActivityRepoImpl.java @@ -61,6 +61,22 @@ public static RemoteActivityRepoImpl getInstance(Context ctx) { public RemoteActivityRepoImpl(Context ctx) { super(ctx); mContext = ctx; + mBackgroundTasksListener = new BackgroundTasksHandlerThread.Listener() { + @Override + public void onDone(Object[] parameters, Object response, BackgroundTask task) { + if (task == BackgroundTask.READ_ACTIVITY) { + List activities = (List) response; + LogUtil.d(RemoteActivityRepoImpl.class.getName(), activities.size() + " activities have been read."); + for (Activity activity : activities) { + OnReadDoneCallback callback = invokeActivityReadCallback(activity); + if (callback != null) { + LogUtil.d(RemoteActivityRepoImpl.class.getName(), "Invoking callback for " + activity.toString()); + callback.onRead(activity); + } + } + } + } + }; } private String getRemoteHost() { @@ -179,7 +195,9 @@ public void readActivityAsync(ActivityKey key, OnReadDoneCallback callback, Back synchronized (mActivityReadRequestCallbacks) { mActivityReadRequestCallbacks.put(key.getId(), callback); } - initBackgroundTasksListener(tasksHandlerThread); + + // addListener enforces that the listener is only added once + tasksHandlerThread.addListener(mBackgroundTasksListener); tasksHandlerThread.queueReadActivity(new ObjectIdentifierBean(key.getId()), this); } } else { @@ -187,30 +205,6 @@ public void readActivityAsync(ActivityKey key, OnReadDoneCallback callback, Back } } - private void initBackgroundTasksListener(BackgroundTasksHandlerThread tasksHandlerThread) { - if (mBackgroundTasksListener == null) { - synchronized (this) { - if (mBackgroundTasksListener == null) { - mBackgroundTasksListener = new BackgroundTasksHandlerThread.Listener() { - @Override - public void onDone(Object[] parameters, Object response, BackgroundTask task) { - if (task == BackgroundTask.READ_ACTIVITY) { - List activities = (List) response; - for (Activity activity : activities) { - OnReadDoneCallback callback = invokeActivityReadCallback(activity); - if (callback != null) { - callback.onRead(activity); - } - } - } - } - }; - } - tasksHandlerThread.addListener(mBackgroundTasksListener); - } - } - } - @Override public Category readCategoryFull(CategoryKey key) { //TODO: implement/overload/fix this method. High priority. diff --git a/src/se/devscout/android/util/concurrency/BackgroundTasksHandlerThread.java b/src/se/devscout/android/util/concurrency/BackgroundTasksHandlerThread.java index 5230716..dae1542 100644 --- a/src/se/devscout/android/util/concurrency/BackgroundTasksHandlerThread.java +++ b/src/se/devscout/android/util/concurrency/BackgroundTasksHandlerThread.java @@ -20,6 +20,15 @@ public static interface BackgroundTaskExecutor { Object run(Object[] params, Context context); } + + private static final Map EXECUTORS = new HashMap(); + + static { + for (BackgroundTask backgroundTask : BackgroundTask.values()) { + EXECUTORS.put(backgroundTask, backgroundTask.createExecutor()); + } + } + private Handler mHandler; private Handler mResponseHandler; private Context mContext; @@ -58,7 +67,7 @@ public void queueSetFavourites() { queueTask(BackgroundTask.SET_FAVOURITES); } - public void queueReadActivity(final ActivityKey activityKey, final RemoteActivityRepoImpl remoteActivityRepo) { + public synchronized void queueReadActivity(final ActivityKey activityKey, final RemoteActivityRepoImpl remoteActivityRepo) { remoteActivityRepo.addPendingActivityReadRequests(activityKey); queueTask(BackgroundTask.READ_ACTIVITY, remoteActivityRepo); @@ -68,12 +77,12 @@ public void queueCleanCache() { queueTask(BackgroundTask.CLEAN_CACHE); } - public synchronized void queueGetMediaResource(ImageView imageView, URI uri, int maxFileSize) { + public void queueGetMediaResource(ImageView imageView, URI uri, int maxFileSize) { LogUtil.d(BackgroundTasksHandlerThread.class.getName(), "Wants to display " + uri + " in an image view."); queueTask(BackgroundTask.DISPLAY_IMAGE, imageView, uri, Integer.valueOf(maxFileSize)); } - private void queueTask(BackgroundTask task, Object... parameters) { + private synchronized void queueTask(BackgroundTask task, Object... parameters) { taskCount++; mTaskParameters.put(taskCount, parameters); if (mHandler == null) { @@ -84,25 +93,35 @@ private void queueTask(BackgroundTask task, Object... parameters) { } } - public void close() { + public synchronized void close() { + LogUtil.d(BackgroundTasksHandlerThread.class.getName(), "Closing and clearing"); mListeners.clear(); - for (BackgroundTask task : BackgroundTask.values()) { - mHandler.removeMessages(task.ordinal()); + mListeners = null; + if (mHandler != null) { + for (BackgroundTask task : BackgroundTask.values()) { + mHandler.removeMessages(task.ordinal()); + } } mTaskParameters.clear(); + mTaskParameters = null; } - public void addListener(Listener listener) { - mListeners.add(listener); - LogUtil.d(BackgroundTasksHandlerThread.class.getName(), "Added listener " + listener.toString()); + public synchronized void addListener(Listener listener) { + if (!mListeners.contains(listener)) { + mListeners.add(listener); +// LogUtil.d(BackgroundTasksHandlerThread.class.getName(), "Added listener " + listener.toString()); + } } - public void removeListener(Listener listener) { - mListeners.remove(listener); - LogUtil.d(BackgroundTasksHandlerThread.class.getName(), "Removed listener " + listener.toString()); + public synchronized void removeListener(Listener listener) { + if (mListeners.contains(listener)) { + mListeners.remove(listener); +// LogUtil.d(BackgroundTasksHandlerThread.class.getName(), "Removed listener " + listener.toString()); + } } private void fireOnDone(Object[] parameters, Object response, BackgroundTask task) { +// LogUtil.d(BackgroundTasksHandlerThread.class.getName(), "Number of listeners: " + mListeners.size()); for (Listener listener : mListeners) { listener.onDone(parameters, response, task); } @@ -110,27 +129,29 @@ private void fireOnDone(Object[] parameters, Object response, BackgroundTask tas private class MessageHandler extends Handler { - private Map mExecutors = new HashMap(); - - { - for (BackgroundTask backgroundTask : BackgroundTask.values()) { - mExecutors.put(backgroundTask, backgroundTask.createExecutor()); - } - } - @Override public void handleMessage(final Message msg) { - final Object[] parameters = mTaskParameters.get(msg.obj); + final Object[] parameters; + Object obj = msg.obj; final BackgroundTask task = BackgroundTask.values()[msg.what]; - LogUtil.i(BackgroundTasksHandlerThread.class.getName(), "Executing background task " + task.name()); - final Object result = mExecutors.get(task).run(parameters, mContext); - mTaskParameters.remove(msg.obj); +// LogUtil.d(BackgroundTasksHandlerThread.class.getName(), "Background task " + obj + ": " + task.name() + " STARTED"); + synchronized (BackgroundTasksHandlerThread.this) { + parameters = mTaskParameters.get(obj); + } +// LogUtil.d(BackgroundTasksHandlerThread.class.getName(), "Background task " + obj + ": " + task.name() + " BEFORE RUN"); + final Object result = EXECUTORS.get(task).run(parameters, mContext); +// LogUtil.d(BackgroundTasksHandlerThread.class.getName(), "Background task " + obj + ": " + task.name() + " AFTER RUN"); + synchronized (BackgroundTasksHandlerThread.this) { + mTaskParameters.remove(obj); + } postReponse(new Runnable() { @Override public void run() { +// LogUtil.d(BackgroundTasksHandlerThread.class.getName(), "Background task postResponse/fireOnDone"); fireOnDone(parameters, result, task); } }); +// LogUtil.d(BackgroundTasksHandlerThread.class.getName(), "Background task " + obj + ": " + task.name() + " FINISHED"); } }