Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiple Async Task Hanging the App

In my android App, I use multiple AsyncTask using THREAD_POOL_EXECUTOR which makes the tasks run in parallel. Sometime the app hangs. Below is the code I use.

  1. Could you please let me know how to fine tune so as to avoid any hanging issue ?
  2. How to find the point in which app is hanging ?

    new fetchInitialCoinsParallel().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, url);
    
    prefCoinList = getPrefCoin();
    if(prefCoinList.size()>0){
        for(int i=0;i<prefCoinList.size();i++){
            new fetchAltCoinsParallel().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, url);
        }
    }
    
    public class fetchAltCoinsParallel extends AsyncTask<String, String, String> {
    @Override
    protected void onPreExecute() {
    }
    
    protected String doInBackground(String... params) {
        try {
            InputStream is = getDataFromURL(params[0]);
            if(is!=null){
                BufferedReader br = new BufferedReader(new InputStreamReader(is));
                synchronized(this){
                    brList.add(br);
                }
    
            }else{
                prefCoinNotLoadedTimeOutCount=prefCoinNotLoadedTimeOutCount+1;
            }
    
    
            if(brList.size()==prefCoinList.size()-prefCoinNotLoadedTimeOutCount){
                try {
                    loadAltCoins(getAltCoinDataParallel());
                } catch (IOException e) {
                    e.printStackTrace();
                }
    
                maingame.dataReady=true;
            }
    
        } catch (IOException e) {
            e.printStackTrace();
        } 
        return null;
    }
    
    protected void onPostExecute(String params) {
    }
    protected void onProgressUpdate(String... progress) {
    }
    

    }

Thread details enter image description here

like image 597
iappmaker Avatar asked Jan 18 '18 03:01

iappmaker


People also ask

Can we run multiple async task at a time?

NOTE : As for limitations, we should mention that AsyncTask always has to executed from the main thread and we can't call execute() twice in the same object; therefore, they cannot loop. if we execute more than one AsyncTask at a time, they will run sequentially by the default version from Android 3.0 onwards.

How many times an instance of AsyncTask can be executed?

AsyncTask instances can only be used one time.

How do I wait for async tasks to complete?

You will need to call AsyncTask. get() method for getting result back and make wait until doInBackground execution is not complete. but this will freeze Main UI thread if you not call get method inside a Thread.

Does async task run on main thread?

AsyncTask is a wrapper class provided by android to perform all the heavy duty tasks in the background and relieve your main UI thread from this burden. An AsyncTask starts on the UI thread and push all the heavy tasks like network calls, database calls etc, on the asyncTask class which starts a background thread.


2 Answers

Instead of using Async Tasks, i recommend using RXJAVA for this purpose.

Here is the disadvantage given for Async Task: https://stackoverflow.com/a/9654445/9100553

Using RxJava will solve this problem, here is an perfect blog which can solve your problem of Multi Threading using RxJava.

http://www.nurkiewicz.com/2017/09/idiomatic-concurrency-flatmap-vs.html

(Read the second half) Both flatmap and parallel operators would be useful in your case.

like image 60
fi - Anand Dubey Avatar answered Sep 20 '22 03:09

fi - Anand Dubey


Check the AsyncTaskLoader concept. This feature is supported by Android community introduced in API level 11 along with Honeycomb features.

AsyncTaskLoader solved the lot of limitations & workaround solutions of the AsyncTask.java

Official : https://developer.android.com/reference/android/content/AsyncTaskLoader.html

Good Sample: https://medium.com/google-developers/making-loading-data-on-android-lifecycle-aware-897e12760832

public class JsonAsyncTaskLoader extends AsyncTaskLoader<List<String>> {
    // You probably have something more complicated
    // than just a String. Roll with me
    private List<String> mData;

    public JsonAsyncTaskLoader(Context context) {
        super(context);
    }

    @Override
    protected void onStartLoading() {
        if (mData != null) {
            // Use cached data
            deliverResult(mData);
        } else {
            // We have no data, so kick off loading it
            forceLoad();
        }
    }

    @Override
    public List<String> loadInBackground() {
        // This is on a background thread
        // Good to know: the Context returned by getContext()
        // is the application context
        File jsonFile = new File(
                getContext().getFilesDir(), "downloaded.json");
        List<String> data = new ArrayList<>();
        // Parse the JSON using the library of your choice
        // Check isLoadInBackgroundCanceled() to cancel out early
        return data;
    }

    @Override
    public void deliverResult(List<String> data) {
        // We’ll save the data for later retrieval
        mData = data;
        // We can do any pre-processing we want here
        // Just remember this is on the UI thread so nothing lengthy!
        super.deliverResult(data);
    }
}
like image 26
Takermania Avatar answered Sep 21 '22 03:09

Takermania