Replace Nested AsyncTasks

asynctask library android
android asynctask alternative
asynctask deprecated
asynctask get
asynctask cancel
what is asynctask in android
asynctask example in android androidhive
asynctask<void, void, void

In my Android application I have several Activities that all connect to one service. This service establishes a connection to a server and handles the sending and retrieving of data (xml files in most cases). Inside of my Activities I call the service functions inside of AsyncTask, because I need to do following actions based on the answer of the server. Here is an example of the structure:

String xmlString = "<myXmlString><myDataObject></myDataObject></myXmlString>";

final AsyncTask<Void, Void, Boolean> myTask = new AsyncTask<Void, Void, Boolean>() {
    @Override
    protected void onPreExecute() {
        super.onPreExecute();

        showProgressDialog("Send Data...");
    }

    @Override
    protected Boolean doInBackground(Void... params) {
        int rc = mService.callMethod("MYFUNCTION", xmlString);
        if (rc == 0) {
            return true;
        }
        else {
            return false;
        }
    }

    @Override
    protected void onPostExecute(Boolean success) {
        hideProgressDialog();

        if (success) {
            // handle received data
            // here it also might occur that another AsyncTask is called
            // e.g.: final AsyncTask<Void, Void, Boolean> nestedTask = new AsyncTask<Void, Void, Boolean>() { ... }
        } else {
            // handle error
        }
    }
};

myTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);

Handler handler = new Handler();
Runnable taskCanceler = new Runnable() {
    @Override
    public void run() {
        if (myTask.getStatus() == AsyncTask.Status.RUNNING) {
            myTask.cancel(true);

            hideProgressDialog();
        }
    }
};
handler.postDelayed(taskCanceler, 15000);

Since I updated Android Studio it says that "This AsyncTask should be static or leaks might occur". Furthermore the nested AsyncTasks can be quite confusing sometimes, but they depend on each other so I don't really know how to change those tasks to static classes. Should I use a different approach for my needs or can I transform them into static classes and still keep the nested logic alive?

I hope I could make my issues clear. Thanks in advance!

Asyntasks were introduced as a background method of synchronization with the ability to post results to main thread when they finish. However, they have big limitations when the logic is complicated.

They are hard to cancel properly, if they are not used correctly they can leak memory and they are cumbersome to use when there are several operations to run.

Finally, they have a hard limit on the number of them that you can execute at the same time.

Here, you will find a list of libraries that you can use as a replacement of Asynctask

If you are a more experienced programmer then I suggest you go one step ahead and use one of the following technologies:

RxJava: This has mainstream in android development for the last couple of years. It will help you to handle business logic, and API calls in a reactive way. The learning curve is quite steep at the beginning but later will make your life easier. Here's an intro tutorial

Kotlin Coroutines: If you're into kotlin coroutines present an easy way to handle concurrency. Here you can find some tutorials

Some great alternatives for AsyncTasks - Code Yoga, So lets look at some of great alternatives for replacing AsyncTasks and Performing several Task s in a row will not create nested "pyramid" code as you would  AsyncTask uses a thread pool pattern for running the stuff from doInBackground(). The issue is initially (in early Android OS versions) the pool size was just 1, meaning no parallel computations for a bunch of AsyncTasks. But later they fixed that and now the size is 5, so at most 5 AsyncTasks can run simultaneously.

It seems that you are willing to change your web service access logic.

You should read about Rxjava/RxKotlin and make a quick refactoring with those technologies. At first it can seem complicated, but believe me, once Rx you never go back.

See more here

AsyncTask, Composing multiple web service calls. Now let's say we've managed to get all of that figured out and working ok, but we now need to make a few  Can I use nested AsyncTasks to load images in Andorid? execute for a longer time and I think AsyncTasks are supposed to be used only for out of nested loops

   private static class TASK_NAME extends AsyncTask<Void, Void, Boolean> {
        @Override
        protected void onPreExecute() {
            super.onPreExecute();

            showProgressDialog("Send Data...");
        }

        @Override
        protected Boolean doInBackground(Void... params) {
            int rc = mService.callMethod("MYFUNCTION", xmlString);
            if (rc == 0) {
                return true;
            }
            else {
                return false;
            }
        }

        @Override
        protected void onPostExecute(Boolean success) {
            hideProgressDialog();

            if (success) {
                // handle received data
                // here it also might occur that another AsyncTask is called
                // e.g.: final AsyncTask<Void, Void, Boolean> nestedTask = new AsyncTask<Void, Void, Boolean>() { ... }
            } else {
                // handle error
            }
        }
    };

Then OnCreateView call it like this:

new TASK_NAME().execute();

Replace AsyncTask and AsyncTaskLoader with rx.Observable , From Android Donut multiple async tasks were executed in parallel until Android Honeycomb 3.0 arrived. For Android Honeycomb, multiple AsyncTasks would be​  Multiple AsyncTask In Android on InnovationM Blog | What is AsyncTask AsyncTask is an abstract Android class which helps the Android applications to perform tasks without blocking the UI Thread. AsyncTask is designed to be a helper class around Thread and Handler. Thread Pool Pattern AsyncTask uses a…

Don't bother with the AsyncTasks if you understand basic threads that's enough to get done. AsyncTasks are helpers and they don't help that much. Add something like the following to your service. You generally pass a shared interface (a lambda would do great here, but alas Java7) that will trigger on the response. Then the service does the threading for you. After all it's something that will always happen given the service talks to the server. It always needs to do that in a thread anyway.

    HttpFetch.get(url, new UIResponse() {
        @Override
        public void response(String header, String content) {
        }
    },this);

Since it uses a static class for the Http work there's no leak, and you can just call it and get the response data you want. And since it's the same static class you can obviously just nest them to your hearts delight. So you send it a request and a class for the response and implement the response class.

For example here's the rest of that from when I did that very thing:

public static void get(final URL urir, final Response response, final Activity activity) {
    Runnable run = new Runnable() {
        @Override
        public void run() {
            HttpURLConnection urlConnection = null;
            try {
                urlConnection = (HttpURLConnection) urir.openConnection();
                InputStream stream = new BufferedInputStream(urlConnection.getInputStream());
                final String content = convertStreamToString(stream);
                final String header = urlConnection.getResponseMessage();
                stream.close();

                activity.runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        response.response(header, content);
                    }
                });
            } catch (final IOException e) {
                activity.runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        response.error(e);
                    }
                });
            } finally {
                if (urlConnection != null) urlConnection.disconnect();
            }
        }
    };
    Thread thread = new Thread(run);
    thread.start();
}

static String convertStreamToString(java.io.InputStream is) {
    java.util.Scanner s = new java.util.Scanner(is).useDelimiter("\\A");
    return s.hasNext() ? s.next() : "";
}


public interface Response {
    void response(String header, String content);
    void error(IOException exception);
}

Other classes like RxJava will likely be doing the same thing. Just hand it a request with a response function and do the threading in the service and you're golden.

Android AsyncTasks Parallel Execution, Handler class or the AsyncTasks classes. A Handler is particular useful if you have want to post multiple times data to the main thread. When first introduced the pool size was just 1, meaning no parallel computations for a bunch of AsyncTasks, AsyncTasks were executed serially on a single background thread. Starting with DONUT, this was changed to a pool of threads allowing multiple tasks to operate in parallel. The pool size is 5, so at most 5 AsyncTasks can run simultaneously.

Introduction to background processing in Android, Running multiple AsyncTasks at the same time -- not possible? battery usage by widget users by removing updatePeriodMillis from metadata * and replacing it​  Quick rename How to batch rename multiple files on Windows 10 Having to rename multiple files manually can be a tedious process on Windows 10, but you can use these steps to speed things along.

android.os.AsyncTask java code examples, AsyncTask enables proper and easy use of the UI thread. this was changed to a pool of threads allowing multiple tasks to operate in parallel. Thanks to Donnie Karns for pointing out that async code statements are not (by default) run on another thread. Thanks to Jim Boyer for correcting a "nested" task problem. And: Thanks to Andrew Dennison for reviewing the Allocate() method code which had an unnecessary statement.

AsyncTask | J2ObjC, References: Replace Nested Conditional with Guard Clauses in Refactoring: Improving the Design of Existing Code; Flattening Arrow Code. e.printStackTrace​()  The first and the most straightforward solution came in the form of nested functions as callbacks. This solution led to something called callback hell, and too many applications still feel the burn of it. Then, we got Promises. This pattern made the code a lot easier to read, but it was a far cry from the Don’t Repeat Yourself (DRY) principle.

Comments
  • These seems like a good place to start. I think I will take a closer look at RxJava, because AsyncTask sometimes seems to cause the problems that you mentioned. Thank you for the useful information!
  • Thanks, I will have a closer look at it.
  • I think this will not work for me, because I can not access any non-static members inside a static class. But since I have nested tasks and need do perfom some logical things this doesn't seem to work.
  • of course,you need to make the variables static,just follow the android studio suggestions