Skip to content Skip to sidebar Skip to footer

After Asynctask.execute() Do X() From Activity

This is one I'm not sure how to go about. Basically I have an ASyncTask class thats doing its business as usual in the background. I'd like to do something after its finished. Now

Solution 1:

Option B should work and is sometimes a good option, but sometimes I use anonymous classes for this. When you call it from your activity:

CustomTasktask=newCustomTask() {
    @OverrideprotectedvoidonPostExecute(Long result) {
        super.onPostExecute(result);
        MyActivity.this.doX();
    }
}.execute();

Solution 2:

Option A:

Android API has already provided built-in function for this purpose AsyncTask.get():

CustomTasktask=newCustomTask();
task.execute(passedParams);
Resultresult= task.get(); // <- Block UI thread and waiting for AsyncTask finish.this.doX(result);

As you can see, this is a bad practice as it blocks UI thread and may cause ANR exception, By doing this, you are actually sacrifice the benefit of AsyncTask, and make it running synchronously with UI thread.


Option B and C:

Both are correct way of doing things, by calling doX() method in onPostExecute() method,

AsyncTask, as its name stated, run a background thread asynchronously with UI thread, and once the background thread is finished, onPostExecute method is called on UI thread. There is no way to tell exactly when onPostExecute method is called (i.e. when doInBackground method is finished) at project build time, as it is determined at app run time, the only thing we know is onPostExecute method is guaranteed to be called on UI thread at some point in the future, In another word, when writing code at project build time, we never know exactly when the doInBackground is finished and code execution jump back to UI thread outside onPostExecute method (Unless you implement some waiting mechanism in code like Option A). So the purpose of onPostExecute method is for processing everything after doInBackground method is finish, this is also why the only argument of onPostExecute method is the result returned from doInBackground method.

The difference between Option B and C is whether to implement AsyncTask as inner class or separate class. This has been aksed and discussed many times in StackOverflow. Most people think it is good to separate them for resusability reason or etc. From my point of view, I don't agree with it. Java Programming Language has its reason provide inner class syntax to suit some special coding situations, when talking about code refactoring from a OOP perspective, think more from problem abstraction level, not simply strip inner class out from Activity class at code level. As you can see in your example, by isolating AsyncTask from Activity, you don't gain any real benefit but rather increase the code complexity (need pass activity context reference between classes) to solve problem.

I think you real question is whether or not we should isolate AsyncTask inner class implementation from Activity. For a better OOP code refactoring (reusability, testability and etc.), checkout my answer in this StackOverflow question to see how to isolate business layer from application UI layer properly.

Solution 3:

I was able to implement this feature with an interface:

http://howcanisolve.com/38646/android-java-equivalent-of-ios-block-callbacks

publicinterfaceICallbacks { 
publicvoidonResponse(JSONObject response);
publicvoidonError(VolleyError error);
}

Then in your routine code just put a new instance of Callbacks:

public static void getPassagesForFirebaseUser(FirebaseUser user,
Context context, ICallbacks events) { 
  //here code and call ICallbacks methodsif(result){ events.onResponse(response); }
  if(error){ events.onError(err); }
}

ultimately you can call the method with :

getPassagesForFirebaseUser(user, context, new ICallbacks(){
  @Override
  public void onResponse(JSONObject response){
      //Success !!!
  }
  @Override
  public void onError(VolleyError response){
      //Error !!!
  }
});

Solution 4:

Option B is generally safer. But even then, you need to be careful. You need to store the instance of your Activity (not just the class) in the ASyncTask. And if the Activity gets destroyed while the task is running (what if the user presses the Back button?), you need to inform the task of this so the task doesn't try to call a method on a dead Activity.

And if the Activity comes back to life (after a screen rotation, for example) then you need to reattach the new Activity to the running task.

These things are fiddly.

Post a Comment for "After Asynctask.execute() Do X() From Activity"