What is the best practice for multi-threaded handler on Android?

I have an application that uses several HTTPRequests , for example

  • get session id

  • get some locationdata p>

  • get existing categories

  • (...) and a few more

I created an HTTPRequestHandler that basically manages all AsynTasks for each request ... This works well, but my problem is that I don't know a good way to manage different AsynTasks . For example, you need to get a SessionId Task before you can run GetSomeLocationData Task

So, in my HTTPRequestHandler , I have a queue that runs the dependent AsyncTasks as:

 private void startSessionIdTask(...) { //... GetSessionIdTask mGetSessionIdTask = new GetSessionIdTask(this); mGetSessionIdTask.execute(url); } //and from the postExecute() in GetSessionIdTask I call public void setSessionId(int mSessionId) { mDataHelper.setmSessionId(mSessionId); //set id String url = API_URL + API_GET_FAVORITES + URL_VARIABLE; List<NameValuePair> params = new LinkedList<NameValuePair>(); params.add(new BasicNameValuePair("session_id", getSessionId())); String paramString = URLEncodedUtils.format(params, "utf-8"); url += paramString; //and finally start another Tasks (and so one...) GetLocationsTask mGetLocationsTask = new GetLocationsTask(this); mGetSessionIdTask.execute(url); } 

However, this works fine, but the problem is that (depending on the connection) this queue takes time, and the user can start another AsynTasks , which does not work, because some of the source data has not yet been loaded.

I could set some boolean type like isSessionIdLoaded , or block the user interface for the user, but I wonder if there is any better solution ?!

So my question is: is there a way to put asyntasks in some kind of queue (ArrayList, Map ..) that will be executed in a line?

+4
source share
3 answers

Like Android 3+, AsyncTasks will execute sequentially on AsyncTask.SERIAL_EXECUTOR . Therefore, by default, if you run 2 AsyncTasks

 task1.execute(); task2.execute(); 

Task2 will only be executed if task1 is complete (just check the sdk implementation of AsyncTask.SERIAL_EXECUTOR ). This can be done so that if task 1 never ends for any reason, task2 will never start and you have blocked your application.

If you want your own queue not to depend on the standard SERIAL_EXECUTOR, just use

 public final AsyncTask<Params, Progress, Result> executeOnExecutor (Executor exec, Params... params) 

And provide your own artist (aka threadpool). For one project, I copied the implementation of SERIAL_EXECUTOR to have 2 consecutive queues.

For Android from 2.3 to 1.6, all tasks are parallel by default, similar to calls in Android 3+:

task.executeOnExecutor (AsyncTask.THREAD_POOL_EXECUTOR, NULL);

Unfortunately, in Android 2.3 and below you have no way to specify the artist on which the task / thread will be launched. Therefore, if you want this done sequentially, you must implement it yourself by calling task2 only after task1 has finished explicitly in onPostExecute() . Of course, this concept can be used for a task queue, where the first task will call the next one when it finishes (= ordinal queue of workers). For this you will find a lot of literature and patterns.

+1
source

I'm not quite sure what you are asking, but if you just want the queue to run Runnables to execute in the background thread in sequence, then Executors.newSingleThreadExecutor() might be what you are looking for. This is more complicated than possible, but you can easily find examples and tutorials through google.

0
source

If you need sequential execution, I would recommend switching to IntentService instead of using AsyncTask . See Docs: http://developer.android.com/reference/android/app/IntentService.html

0
source

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


All Articles