Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>My approach is to use delegation design pattern, in general, we can isolate the actual business logic (read data from internet or database or whatsoever) from AsyncTask (the delegator) to BusinessDAO (the delegate), in your AysncTask.doInBackground() method, delegate the actual task to BusinessDAO, then implement a singleton process mechanism in BusinessDAO, so that multiple call to BusinessDAO.doSomething() will just trigger one actual task running each time and waiting for the task result. The idea is retain the delegate (i.e. BusinessDAO) during the configuration change, instead of the delegator (i.e. AsyncTask). </p> <ol> <li><p>Create/Implement our own Application, the purpose is to create/initialize BusinessDAO here, so that our BusinessDAO's lifecycle is application scoped, not activity scoped, note that you need change AndroidManifest.xml to use MyApplication: </p> <pre><code>public class MyApplication extends android.app.Application { private BusinessDAO businessDAO; @Override public void onCreate() { super.onCreate(); businessDAO = new BusinessDAO(); } pubilc BusinessDAO getBusinessDAO() { return businessDAO; } } </code></pre></li> <li><p>Our existing Activity/Fragement are mostly unchanged, still implement AsyncTask as an inner class and involve AsyncTask.execute() from Activity/Fragement, the difference now is AsyncTask will delegate the actual task to BusinessDAO, so during the configuration change, a second AsyncTask will be initialized and executed, and call BusinessDAO.doSomething() second time, however, second call to BusinessDAO.doSomething() will not trigger a new running task, instead, waiting for current running task to finish:</p> <pre><code>public class LoginFragment extends Fragment { ... ... public class LoginAsyncTask extends AsyncTask&lt;String, Void, Boolean&gt; { // get a reference of BusinessDAO from application scope. BusinessDAO businessDAO = ((MyApplication) getApplication()).getBusinessDAO(); @Override protected Boolean doInBackground(String... args) { businessDAO.doSomething(); return true; } protected void onPostExecute(Boolean result) { //Handle task result and update UI stuff. } } ... ... } </code></pre></li> <li><p>Inside BusinessDAO, implement singleton process mechanism, for example:</p> <pre><code>public class BusinessDAO { ExecutorCompletionService&lt;MyTask&gt; completionExecutor = new ExecutorCompletionService&lt;MyTask(Executors.newFixedThreadPool(1)); Future&lt;MyTask&gt; myFutureTask = null; public void doSomething() { if (myFutureTask == null) { // nothing running at the moment, submit a new callable task to run. MyTask myTask = new MyTask(); myFutureTask = completionExecutor.submit(myTask); } // Task already submitted and running, waiting for the running task to finish. myFutureTask.get(); } // If you've never used this before, Callable is similar with Runnable, with ability to return result and throw exception. private class MyTask extends Callable&lt;MyTask&gt; { public MyAsyncTask call() { // do your job here. return this; } } } </code></pre></li> </ol> <p>I am not 100% sure if this will work, moreover, the sample code snippet should be considered as pseudocode. I am just trying to give you some clue from design level. Any feedback or suggestions are welcome and appreciated.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload