29

At a certain point of my AsyncTask, after some validations have been done, I need to spawn off another thread to do some other work. So I'd like two background threads at this point, each doing it's own thing (approx 2-3 seconds to execute each). The idea is to maximize performance on dual core processors like Atrix.

Is it acceptable to create another asynctask & execute it from the first one? Can anyone suggest a better way of doing this?

Thanks!

EDIT: I'm wondering what publishProgress() from the second task would even do... since it was not started from an Activity?

Agna JirKon Rx
  • 2,321
  • 2
  • 29
  • 44
OceanBlue
  • 9,142
  • 21
  • 62
  • 84

4 Answers4

58

Is it acceptable to create another asynctask & execute it from the first one?

Yes, but only inside onProgressUpdate() or onPostExecute() since these methods runs on the UI thread. Therefore, start the second AsyncTask on the UI thread by choosing one of the two methods listed above.

I'm wondering what publishProgress() from the second task would even do... since it was not started from an Activity?

It does exactly the same thing, since you are starting it from the UI thread.

Wroclai
  • 26,835
  • 7
  • 76
  • 67
  • What about `onPreExecute()` which also runs on the UI thread? http://developer.android.com/reference/android/os/AsyncTask.html#onPreExecute%28%29 – ban-geoengineering Dec 21 '14 at 19:36
  • @ban-geoengineering the onPreExecute() method, as the name implies, will be executed before all other method in the AsyncTask, however, regardless that it is also executed in the UI thread. Basically, in case you need to do some computation or logic every time before the doInBackground(...) starts, this is your method. – tsukanomon Jun 02 '15 at 13:11
  • Cheers, but I was asking/suggesting whether `onPreExecute()` could be a suitable place to create another AsyncTask from? – ban-geoengineering Jun 02 '15 at 16:57
10

If you are looking for a mechanism of executing multiple async tasks, from 3.0 and above it supports a method called executeOnExecutor which will allow you to schedule tasks in parallel on a pool of thread managed by Async Task.

advantej
  • 20,155
  • 4
  • 34
  • 39
  • +1 for the info. This particular application I am developing is targeting 2.2 and above, so cannot use here, but good to know for future. – OceanBlue Apr 25 '11 at 17:43
2

An AsyncTask is useful for doing some background work while communicating with the main thread to handle UI changes. It appears that this is not your case.

Besides, an AsyncTask must be executed from the main thread. From the AsyncTask reference:

There are a few threading rules that must be followed for this class to work properly:

  • The task instance must be created on the UI thread.
  • execute(Params...) must be invoked on the UI thread.

You can a take a look at this article and see what fits you best.

aromero
  • 25,681
  • 6
  • 57
  • 79
0

This can be done using message passing concurrency and a single handler. Proof of concept code follows:

private Handler myHandler= new Handler(){
    @Override
    public void  handleMessage(Message msg){         
        switch(msg.what){
            case 0:
                Toast.makeText(Main.this,"Message0", Toast.LENGTH_SHORT).show();
                Thread thread= new Thread( new Runnable() {
                    public void run() {
                        try {
                            Thread.sleep(3000);
                        }
                        catch(Exception e){}
                        myHandler.sendEmptyMessage(2);
                    }       
                });
                thread.setDaemon(true); // <== I am a service provider. KILL ME if the non-daemon thread ConfuseText quits
                thread.start();   

            break;
            case 1:
                Toast.makeText(Main.this,"Message1", Toast.LENGTH_SHORT).show();
                break;
            case 2:
                Toast.makeText(Main.this,"Message2", Toast.LENGTH_SHORT).show();
                break;
            default:
                super.handleMessage(msg);
                break;
        }
    }
};

I launched the first thread on a button click as in:

 ON CLICK HANDLER
            threadButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View arg0) {
                // TODO Auto-generated method stub
                Thread thread= new Thread( new Runnable() {
                    public void run() {
                        try {
                        Thread.sleep(1000);
                        }
                        catch(Exception e){ 
                        }
                        myHandler.sendEmptyMessage(0);
                        try {
                        Thread.sleep(3000);
                        }
                        catch(Exception e){ 
                        }
                        myHandler.sendEmptyMessage(1);
                    }
                });
                thread.setDaemon(true); // <== I am a service provider. KILL ME if the non-daemon thread ConfuseText quits
                thread.start();
            }
});

The calls to thread sleep is to mimic a time intensive task.

JAL
  • 3,319
  • 2
  • 20
  • 17