nghiduong90
nghiduong90

Reputation: 107

Communication between main thread and worker threads in android

In my very first android project, I do some data manipulation, so I use multi-threading approach.

In MainActivity, I created multiple Runnable object and use ExecutorService to run all the threads. As my understanding, all threads are put in message queue and executed in turn. And the because the main thread is already in the queue, it will be executed before starting other threads. Is there any way that I can make the main thread wait for other threads to finish and then continue?

   @Override
protected void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    //call MyFunction here
}
private List<Pair[]> myFunction(int dataInput) throws InterruptedException {
    ExecutorService executorService = Executors.newFixedThreadPool(12);
    MyTask MyTask = new MyTask();
    for (int i = 0; i < gallerySize; ++i) {
        final int index = i;
        Runnable runnable = MyTask.runLongOperationWithThread(new MyTask.DataCallback(){
            @Override
            public void onSuccess(double[] scores) {
                // get data back to main thread
            }

            @Override
            public void onError(Exception ex) {
                //TODO: log this error out to file
            }
        });
        executorService.execute(runnable);
    }

    // try to get back all data from multi threading and do some operations
    return returnList;
}

Do Looper and Handler help in this case?

And please correct me if I have any misunderstanding in android concept and threading.

Thanks.

Upvotes: 2

Views: 2491

Answers (1)

fikr4n
fikr4n

Reputation: 3420

In Android, stopping main thread is discouraged. The system will tell the user that the app is not responding. However, you can "notify" the main thread that the background thread has finished its work. Once the main thread knows this, it will do something. It is common in Android, it is what AsyncTask for.

However, AsyncTask is used for a simple one thread. In your case, one of the solution is to combine ExecutorService and AsyncTask. In doInBackground method of AsyncTask instance you make, use ExecutorService like usual, and wait it to finish by either shutdown(); awaitTermination() or invokeAll(). Read this question/answer for more information about how to wait ExecutorService to finish.

private class WrappingTask extends AsyncTask<Void, Void, Exception> {
    protected Exception doInBackground(Void... args) {
        ExecutorService taskExecutor = Executors.newFixedThreadPool(12);
        for (. . .) {
            taskExecutor.execute(new MyTask(. . .));
        }
        taskExecutor.shutdown();
        try {
            taskExecutor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
        } catch (InterruptedException e) {
            . . .
            return e;
        }
        return null;
    }

    protected void onPostExecute(Exception error) {
        // Notify the user that the task has finished or do anything else
        // and handle error
    }
 }

In case of long running task

AsyncTask is a handy class to make threading and communicating (to main thread) easier. The problem for long running task is that the user can leave the Activity (and then come again), or there is an incoming call, etc. If you don't handle this Activity lifecycle with care, it is so "dangerous", AsyncTask does not handle this.

Long running task should be run in a Service. Note that Service is also run in the main thread, so the approach would be the same, unless you use IntentService. In case of IntentService, just execute all of the threads (formerly in doInBackground) in the onHandleIntent method and wait it there, this method is called on a worker thread.

Communicating Service with Activity and maintaining consistency of Activity's state through its lifecycle is a long story. You better read the documentation in "a full concentration" with a cup of coffee :D. This might helps:

Upvotes: 1

Related Questions