How can I copy two background tasks?

I have 2 AsyncTasks running in a fragment.
AsyncTasks are defined in a different class, and not in the internal private fragment classes.
The problem with me is that it turned out now that I need AsyncTaskX to wait until AsyncTaskY completes its onPostExecute
How can i solve this?
I thought to use countdownlatch, but AsyncTaskY is in a different class, and I'm not sure if this is the best way to code this?
Is there a way to check if AsyncTask has ended completely?

Update:
I was wondering if task.execute().get() onPostExecute after onPostExecute ?

Update 2:
Does the call to CountDownLatch.countDown() call from the UI thread?

+5
source share
4 answers

Is it really difficult to determine without seeing your code. One dirty solution would be to add a static Boolean value and then add a recursive timer. This is not the best programming method, but from what I read, it will certainly work.

Create static boolean in any class

 static boolean onPostExecuteFinished; 

in AsyncTask, which should be finished, first set it to true

 ClassName.onPostExecuteFinished = true; 

In a class that must wait, you make a recursive method, waiting for it to complete. I recommend using a handler.

 public void nameOfRecursiveMethodHere() Handler handler = new Handler() handler.postDelated(new runnable........{ if (ClassName.onPostExecuteFinished) { //Great it is finished do what you need } else { //Not finished call this method again nameOfRecursiveMethodHere(); } }),(put how often you want it to check in milliseconds here); 
+1
source

Instead of using 2 AsyncTasks, I would suggest using RxJava and RxAndroid . Concurrency is much simpler.

For example, you can do the following to synchronize your asynchronous jobs:

 Observable<Object1> job1 = Observable.fromCallable(() -> yourCall2()); Observable<Object2> job2 = Observable.fromCallable(() -> yourCall2()); Observable.combineLatest(job1, job2, (object1, object2) -> yourMethod()) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(...); 

This is just a small, incomplete example, but should show how to achieve what you want. I used Lambda Expressions to shorten the code. This is done using Retrolambda . You can achieve the same result with the zip operator.

+1
source

As Andy Turner explained, using CountDownLatch is possible, you can also use Semaphore to signal the completion of a task from another.

please check this link: http://tutorials.jenkov.com/java-concurrency/semaphores.html

+1
source

AsyncTasks are executed sequentially on a single background thread ( from API 11 ).

A small test:

 private static class AsyncTaskX extends AsyncTask<Void, Void, Void>{ @Override protected Void doInBackground(Void... params) { for (int i = 0; i < 10; i++){ Log.i("test order", "ping X "+ i); try { Thread.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } } return null; } } private static class AsyncTaskY extends AsyncTask<Void, Void, Void>{ @Override protected Void doInBackground(Void... params) { for (int i = 0; i < 10; i++){ Log.i("order", "ping Y" + i); try { Thread.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } } return null; } } 

Logs:

 test order: ping X 0 test order: ping X 1 test order: ping X 2 test order: ping X 3 test order: ping X 4 test order: ping X 5 test order: ping X 6 test order: ping X 7 test order: ping X 8 test order: ping X 9 order: ping Y0 order: ping Y1 order: ping Y2 order: ping Y3 order: ping Y4 order: ping Y5 order: ping Y6 order: ping Y7 order: ping Y8 order: ping Y9 

So long working a worker can block others.

task.execute (). get () will return before onPostExecute, and you will block the UI thread.

Check out general information about processes and threads and some errors .

Runtime also matters, since AsyncTask should only be used for tasks / operations that take quite a few seconds.

+1
source

Source: https://habr.com/ru/post/1247552/


All Articles