From c66365b002ea0cb6fdec9f4d95165a8e0feca06d Mon Sep 17 00:00:00 2001 From: Pierre HUBERT Date: Tue, 4 Sep 2018 10:30:51 +0200 Subject: [PATCH] Create SafeAsyncTasks manager --- .../client/ui/asynctasks/SafeAsyncTask.java | 7 ++ .../ui/asynctasks/SafeAsyncTasksManager.java | 108 ++++++++++++++++++ .../client/ui/fragments/AbstractFragment.java | 45 ++++++++ .../fragments/AbstractPostsListFragment.java | 3 +- .../ui/fragments/LatestPostsFragment.java | 42 +++---- 5 files changed, 177 insertions(+), 28 deletions(-) create mode 100644 app/src/main/java/org/communiquons/android/comunic/client/ui/asynctasks/SafeAsyncTasksManager.java create mode 100644 app/src/main/java/org/communiquons/android/comunic/client/ui/fragments/AbstractFragment.java diff --git a/app/src/main/java/org/communiquons/android/comunic/client/ui/asynctasks/SafeAsyncTask.java b/app/src/main/java/org/communiquons/android/comunic/client/ui/asynctasks/SafeAsyncTask.java index 43af415..1521fcc 100644 --- a/app/src/main/java/org/communiquons/android/comunic/client/ui/asynctasks/SafeAsyncTask.java +++ b/app/src/main/java/org/communiquons/android/comunic/client/ui/asynctasks/SafeAsyncTask.java @@ -50,6 +50,13 @@ public abstract class SafeAsyncTask this.onPostExecuteListener = onPostExecuteListener; } + /** + * Remove current onPostExecuteListener + */ + public void removeOnPostExecuteListener(){ + this.onPostExecuteListener = null; + } + /** * Check whether the a OnPostExecuteListener has been set or not * diff --git a/app/src/main/java/org/communiquons/android/comunic/client/ui/asynctasks/SafeAsyncTasksManager.java b/app/src/main/java/org/communiquons/android/comunic/client/ui/asynctasks/SafeAsyncTasksManager.java new file mode 100644 index 0000000..e7b14f0 --- /dev/null +++ b/app/src/main/java/org/communiquons/android/comunic/client/ui/asynctasks/SafeAsyncTasksManager.java @@ -0,0 +1,108 @@ +package org.communiquons.android.comunic.client.ui.asynctasks; + +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; + +import java.util.ArrayList; + +/** + * SafeAsyncTask manager + * + * Allows an easy management of AsyncTasks + * + * @author Pierre HUBERT + */ +public class SafeAsyncTasksManager { + + /** + * The list of tasks + */ + private ArrayList mTasks = new ArrayList<>(); + + + /** + * Add a task to the manager + * + * @param task The task to add + */ + public void addTask(@NonNull SafeAsyncTask task){ + addTask(task, false); + } + + /** + * Add a task to the manager + * + * @param task The task to add + * @param unsetSimilar Set to true to remove any similar class + */ + public void addTask(@NonNull SafeAsyncTask task, boolean unsetSimilar){ + + if(unsetSimilar) + unsetSpecificTasks(task.getClass()); + + mTasks.add(task); + } + + /** + * Get the first task that belongs to a specific class + * + * @param cls The kind of class to search for + * @return The first task, or null if none found + */ + @Nullable + public SafeAsyncTask getTask(Class cls){ + for(SafeAsyncTask task : mTasks){ + if(task.getClass().equals(cls)) + return task; + } + + return null; + } + + /** + * Remove a task from the manager + * + * @param task The task to removes + */ + public void removeTask(SafeAsyncTask task){ + mTasks.remove(task); + } + + /** + * Unset a task + * + * @param task The task to unset + */ + public void unsetTask(@Nullable SafeAsyncTask task){ + if(task != null) { + task.removeOnPostExecuteListener(); + removeTask(task); + } + } + + /** + * Unset all running tasks + */ + public synchronized void unsetAllTasks(){ + for(SafeAsyncTask task : mTasks){ + if(task != null) + task.removeOnPostExecuteListener(); + + } + + mTasks = new ArrayList<>(); + } + + /** + * Unset only a specific kind of class + * + * @param cls The tasks to disable + */ + public void unsetSpecificTasks(Class cls){ + for (SafeAsyncTask task : mTasks){ + if(task.getClass().equals(cls)) + unsetTask(task); + + } + } +} diff --git a/app/src/main/java/org/communiquons/android/comunic/client/ui/fragments/AbstractFragment.java b/app/src/main/java/org/communiquons/android/comunic/client/ui/fragments/AbstractFragment.java new file mode 100644 index 0000000..a6d84a1 --- /dev/null +++ b/app/src/main/java/org/communiquons/android/comunic/client/ui/fragments/AbstractFragment.java @@ -0,0 +1,45 @@ +package org.communiquons.android.comunic.client.ui.fragments; + +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.support.v4.app.Fragment; + +import org.communiquons.android.comunic.client.ui.asynctasks.SafeAsyncTasksManager; + +/** + * Base fragment for the fragments of the application + * + * Integrates task manager + * + * @author Pierre HUBERT + */ +public abstract class AbstractFragment extends Fragment { + + /** + * Tasks manager + */ + private SafeAsyncTasksManager mTasksManager; + + @Override + public void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + mTasksManager = new SafeAsyncTasksManager(); + } + + @Override + public void onDestroy() { + super.onDestroy(); + + getTasksManager().unsetAllTasks(); + } + + /** + * Get the task manager associated with the fragment + * + * @return The task manager + */ + SafeAsyncTasksManager getTasksManager() { + return mTasksManager; + } +} diff --git a/app/src/main/java/org/communiquons/android/comunic/client/ui/fragments/AbstractPostsListFragment.java b/app/src/main/java/org/communiquons/android/comunic/client/ui/fragments/AbstractPostsListFragment.java index f75021d..71dbf14 100644 --- a/app/src/main/java/org/communiquons/android/comunic/client/ui/fragments/AbstractPostsListFragment.java +++ b/app/src/main/java/org/communiquons/android/comunic/client/ui/fragments/AbstractPostsListFragment.java @@ -7,7 +7,6 @@ import android.os.Bundle; import android.support.annotation.CallSuper; import android.support.annotation.NonNull; import android.support.annotation.Nullable; -import android.support.v4.app.Fragment; import android.support.v4.app.FragmentTransaction; import android.support.v7.widget.DividerItemDecoration; import android.support.v7.widget.LinearLayoutManager; @@ -56,7 +55,7 @@ import java.util.Objects; * Created by pierre on 3/18/18. */ -public abstract class AbstractPostsListFragment extends Fragment +public abstract class AbstractPostsListFragment extends AbstractFragment implements onPostUpdateListener, OnScrollChangeDetectListener, PostsCreateFormFragment.OnPostCreated { /** diff --git a/app/src/main/java/org/communiquons/android/comunic/client/ui/fragments/LatestPostsFragment.java b/app/src/main/java/org/communiquons/android/comunic/client/ui/fragments/LatestPostsFragment.java index 2c8221d..af4bb2b 100644 --- a/app/src/main/java/org/communiquons/android/comunic/client/ui/fragments/LatestPostsFragment.java +++ b/app/src/main/java/org/communiquons/android/comunic/client/ui/fragments/LatestPostsFragment.java @@ -24,11 +24,6 @@ public class LatestPostsFragment extends AbstractPostsListFragment { */ private static final String TAG = "LatestPostsFragment"; - /** - * Load posts task - */ - private GetLatestPostsTask mGetLatestPostsTask; - @Override public void onResume() { super.onResume(); @@ -41,16 +36,7 @@ public class LatestPostsFragment extends AbstractPostsListFragment { @Override public void onStop() { super.onStop(); - unset_all_load_tasks(); - } - - - /** - * Unset all pending load tasks - */ - private void unset_all_load_tasks(){ - if(mGetLatestPostsTask != null) - mGetLatestPostsTask.setOnPostExecuteListener(null); + getTasksManager().unsetAllTasks(); } /** @@ -60,25 +46,28 @@ public class LatestPostsFragment extends AbstractPostsListFragment { */ private boolean is_loading_posts() { - return mGetLatestPostsTask != null && - mGetLatestPostsTask.hasOnPostExecuteListener() && - !mGetLatestPostsTask.isCancelled() && - mGetLatestPostsTask.getStatus() != AsyncTask.Status.FINISHED; + SafeAsyncTask task = getTasksManager().getTask(GetLatestPostsTask.class); + + return task != null && + task.hasOnPostExecuteListener() && + !task.isCancelled() && + task.getStatus() != AsyncTask.Status.FINISHED; } @Override public void onLoadPosts() { //Get the list of latest posts - unset_all_load_tasks(); - mGetLatestPostsTask = new GetLatestPostsTask(getActivity()); - mGetLatestPostsTask.setOnPostExecuteListener(new SafeAsyncTask.OnPostExecuteListener() { + getTasksManager().unsetSpecificTasks(GetLatestPostsTask.class); + GetLatestPostsTask getLatestPostsTask = new GetLatestPostsTask(getActivity()); + getLatestPostsTask.setOnPostExecuteListener(new SafeAsyncTask.OnPostExecuteListener() { @Override public void OnPostExecute(PostsList posts) { onGotNewPosts(posts); } }); - mGetLatestPostsTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + getLatestPostsTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + getTasksManager().addTask(getLatestPostsTask, true); } @Override @@ -100,14 +89,15 @@ public class LatestPostsFragment extends AbstractPostsListFragment { int start = last_post_id - 1; //Get older posts - mGetLatestPostsTask = new GetLatestPostsTask(getActivity()); - mGetLatestPostsTask.setOnPostExecuteListener(new SafeAsyncTask.OnPostExecuteListener() { + GetLatestPostsTask getLastestPostsTask = new GetLatestPostsTask(getActivity()); + getLastestPostsTask.setOnPostExecuteListener(new SafeAsyncTask.OnPostExecuteListener() { @Override public void OnPostExecute(PostsList posts) { onGotNewPosts(posts); } }); - mGetLatestPostsTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, start); + getLastestPostsTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, start); + getTasksManager().addTask(getLastestPostsTask, true); } @Override