XelharK
XelharK

Reputation: 609

Android AsyncTask with notification

I am currently starting to develop Android applications, and I must say that it all came out very very simple and straightforward.

I have a small question about the AsyncTask. Maybe I've been doing something wrong, but here's the situation.

I have a small app that needs to load a list's content from the web. I developed everything based on fake requests, and it all came out awesome. Then I updated the code with actual requests and got the 'Network on main thread error'. So I decided to switch to AsyncTask.

I was wondering if I could let AsyncTask just do the asynchronous work, and handle the result somewhere else (where I actually have the GUI connections and everything). I thought that in terms of readability and logic it makes more sense to have all the code that handles the interface in the Activity, but how could I let the Activity know when a task was completed?

I wrote these simple classes and interfaces (and it works) but I wanted to know from you if this is a good thing or there are better methods to do that.

So, here's the code:

public interface AsyncDelegate {

    public void executionFinished(LazyLoaderWithDelegate lazyLoaderWithDelegate);
}

This is a simple interface. The purpose is to have the Activity implement this and handle the 'executionFinished' method. Something like a listener.

import android.os.AsyncTask;

public class LazyLoaderWithDelegate<Params, Progress, Result> extends AsyncTask<Params, Progress, Result>{
    AsyncDelegate delegate;

    Result result;

    public LazyLoaderWithDelegate(AsyncDelegate delegate){
        this.delegate = delegate;
    }

    @Override
    protected Result doInBackground(Object... params) {
        //This will be Overridden again from the subclasses anyway.
        return null;
    }

    @Override
    protected void onPostExecute(Result r){
        this.result = r;
        delegate.executionFinished(this);
    }

    public Result getResult(){
        return result;
    }

}

This class basically gives a skeleton structure to notify the delegate when the task is finished.

That's all. Here's an example of using this classes:

public class LazyVideoLoader extends LazyLoaderWithDelegate<Void, Void, List<List<Video>>>{

    public LazyVideoLoader(AsyncDelegate delegate) {
        super(delegate);
    }

    @Override
    protected List<Video> doInBackground(Void ...params) {
        return ServerInterface.getVideos();
    }

}

public class MainActivity extends Activity implements AsyncDelegate {
    private LazyVideoLoader videoLoader;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        /*
         * Set up the lazy loaders
         */
        videoLoader = new LazyVideoLoader(this);
        videoLoader.execute();
    }

    @Override
    public void executionFinished(LazyLoaderWithDelegate task) {
        if(task == videoLoader){
            List<Video> result = videoLoader.getResult();
            //Do whatever you need...
        }

}

Upvotes: 1

Views: 3614

Answers (2)

Steve Benett
Steve Benett

Reputation: 12933

If I understand this correct you have a seperate class, which runs an AsyncTask. If the task is completed the as callback used interface informs the Activity. This is good if you think in components to make the code more modular.

The most common practice is to use an AsyncTask as an inner class in an Activity. If you just wanna download a picture or something similar with relative small size this is the prefered way. Because you can access all fields in your inner class, which makes things easier than passing them around in constructors/interfaces.

Don't use an AsyncTask in an extra Class just for readability. If you have to do some fair calculation/modification on the results with different methods your way is ok.

Upvotes: 1

Dulanga
Dulanga

Reputation: 1346

Everything you run on onPostExecute is in the UI Thread. Also you can run a code on UI Thread once a certain part of the work is done simply on onProgressUpdate by calling publishProgress on doInBackground.

Refer this for more information. It has everything you need to know about AsyncTask.

Upvotes: 3

Related Questions