Reputation: 3005
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) {
}
}
Upvotes: 11
Views: 1410
Reputation: 1385
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);
}
}
Upvotes: 1
Reputation: 89
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.
Upvotes: 1