-1

I have an AsyncTask as public class like below,

public class FetchFromTCWebTask extends AsyncTask<String, Void, String> {
MainActivity mainActivity;
int requestId;
private final static String DEBUG_TAG = "FetchFromTCWebTask";

FetchFromTCWebTask(MainActivity activity, int id) {
    mainActivity = activity;
    requestId = id;
}

@Override
protected String doInBackground(String[] urls) {
    // params comes from the execute() call: params[0] is the url.
    try {
        return downloadUrl(urls[0]);
    } catch (IOException e) {
        return "Unable to retrieve web page. URL may be invalid.";
    }
}

@Override
protected void onPostExecute(String result) {
    mainActivity.loadFinished(result);
}
// Reads an InputStream and converts it to a String.
public String readIt(InputStream stream, int len) throws IOException, UnsupportedEncodingException {
    Reader reader = null;
    reader = new InputStreamReader(stream, "UTF-8");
    char[] buffer = new char[len];
    reader.read(buffer);
    return new String(buffer);
}

public interface UIListner {
    public void loadFinished(String result);

    public void loading(int progress);
}

}

Now i want to call it as

(new FetchFromTCWebTask(actviity,1)).execute(url);
(new FetchFromTCWebTask(actviity,2)).execute(url);
(new FetchFromTCWebTask(actviity,3)).execute(url);

Now My Question is , there any way to do like it in parallel and get back the results separately for 1,2 and 3 ? if yes then how ?

SimpleCoder
  • 1,665
  • 1
  • 21
  • 34

2 Answers2

1

Use a thread pool to achieve this.

(new FetchFromTCWebTask(actviity, 1)).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, url)
(new FetchFromTCWebTask(actviity, 2)).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, url)
(new FetchFromTCWebTask(actviity, 3)).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, url)

ExecuteOnExecutor


Since I figure you're about to ask me how to write this (for the twentieth time), here's a small example. I omitted some parts since they're not relevant. This is how you would send the id back to the activity to distinguish between them. If you needed to do different tasks inside of onPostExecute then just use a switch/case statement.

public class FetchFromTCWebTask extends AsyncTask<String, Void, String>
{
    MainActivity mainActivity;
    int requestId;

    FetchFromTCWebTask(MainActivity activity, int id)
    {
        mainActivity = activity;
        requestId = id;
    }

    ...

    @Override
    protected void onPostExecute(String result)
    {
        mainActivity.loadFinished(result, requestId);
    }

    public interface UIListner
    {
        public void loadFinished(String result, int id);
        public void loading(int progress);
    }
}
d0nut
  • 2,835
  • 1
  • 18
  • 23
  • this is already done when you call execute. see https://android.googlesource.com/platform/frameworks/base/+/refs/heads/master/core/java/android/os/AsyncTask.java#538 – petey Aug 11 '15 at 14:55
  • @petey actually you're incorrect. `THREAD_POOL_EXECUTOR` is not the executor that is used when you use `execute(param)`. That is a `SerialExecutor` (line 207) not the `ThreadPoolExecutor` (line 199). Nice try, though – d0nut Aug 11 '15 at 14:59
  • @petey just in case you're trying to track everything down `return executeOnExecutor(sDefaultExecutor, params);` (line 539) *and* `private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR;` (line 212) – d0nut Aug 11 '15 at 15:02
  • @iismathwizard, in your answer , you passed 1 in all instances, now how i can i differentiate the results in onPostExecute(String result) for each request ?. In my question i tried to achieve it by passing different id e.g 1,2,3 so that i can distinguish in asynctask itself. – SimpleCoder Aug 11 '15 at 16:57
  • @SimpleCoder then pass an id? Not hard – d0nut Aug 11 '15 at 17:06
  • @iismathwizard, It ll be really helpful if u provide the example by code . i used the term "id" metaphorically to distinguish the request. – SimpleCoder Aug 11 '15 at 17:17
  • @SimpleCoder so i'm assuming that little number in the async task was that `id`. Why don't you just change the number?!?@?!?!??!?!?!??!?!?!??!?!?!11?!??!?! – d0nut Aug 11 '15 at 17:33
  • @SimpleCoder i just edited the answer for you since that was apparently difficult to understand – d0nut Aug 11 '15 at 17:33
  • @SimpleCoder everything making sense now?? – d0nut Aug 11 '15 at 18:08
  • @iismathwizard, still i am not getting how results would be distinguished in onPostExecute() ? – SimpleCoder Aug 11 '15 at 18:11
  • @SimpleCoder is this a homework assignment? You passed in an id, right? it's a number that I see right there in your asynctask definition. In `onPostExecute` you can use that number to distinguish which asynctask it is since it will be different for the 3 requests. What exactly is hard to understand? But serious question: is this a homework assignment since you seem to be lacking in some fundamentals here. – d0nut Aug 11 '15 at 18:12
  • @iismathwizard , i just started coding in android months back . I was confused in the different or same instances. Now i get it and my code is working as expected. – SimpleCoder Aug 11 '15 at 18:27
0

Use custom thread pool.

Why not use build in thread pool(AsyncTask.THREAD_POOL_EXECUTOR)? Its got quite small limit of tasks it can handle. How can you tell that build in pool aint working? Its simple, AsyncTask wont start :)

Adam Fręśko
  • 1,064
  • 9
  • 14
  • at bare minimum `THREAD_POOL_EXECUTOR` will support 3 concurrent tasks running. It can support more if the device has more CPU cores. In OP's example, `THREAD_POOL_EXECUTOR` will work just fine. – d0nut Aug 11 '15 at 17:43
  • But its worth to point that. Its a source of much head scratching when you encounter that first time. – Adam Fręśko Aug 11 '15 at 17:45
  • @Adam , my original problem was to differentiate the results in onPostExecute method. – SimpleCoder Aug 11 '15 at 18:15