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.
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
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.
AsyncTask instances can only be used one time.
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.
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.
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.
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);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With