AsyncTask 正在使用相同的线程并将我的所有请求排队

AsyncTask is using the same thread and queueing all my requests

在我的 Android 应用程序中,我发现我的所有 api 呼叫都在排队,而不是同时发生。我假设它们都发布到同一个线程,而我的印象是 AsyncTaskdoInBackground() 创建了一个 new 线程。

public class API extends AsyncTask<String, String, String> {
    public interface Listener {
        void completedWithResult(JSONObject result);
    }
    public Listener listener;
    @Override
    protected String doInBackground(String... strings) {
        if(!canMakeRequest()){
            return internetError().toString();
        }
        String action = strings[0];

        Log.i("API", action +" Sent");
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        Log.i("API", action +" Received");
        return "";
    }

    @Override
    protected void onPostExecute(String json) {
        JSONObject obj;
        obj = new JSONObject(json);
        if(listener != null)listener.completedWithResult(obj);
    }
}

在我的应用程序的很多地方,我都有这样的东西:

API api = new API();
api.listener = new API.Listener() {
    @Override
    public void completedWithResult(JSONObject result) {
        Log.i(tag, "Returned with "+result);
    }
};
api.execute("update-address/");

而且我总是创建 API 的新实例,但我的日志中所有这些调用都是连续发生的,而不是并行发生的:

analytics/log/ Sent
analytics/log/ Returned
get-beta-tester Sent
get-beta-tester Returned
get-following Sent
get-following Returned
get-groups Sent
get-groups Returned
get-follow-requests Sent
get-follow-requests Returned
get-followers Sent
get-followers Returned
analytics/log/ Sent
analytics/log/ Returned
analytics/log/ Sent
analytics/log/ Returned
post-session Sent
post-session Returned
analytics/log/ Sent
analytics/log/ Returned
post-session Sent
post-session Returned
analytics/log/ Sent
analytics/log/ Returned
analytics/log/ Sent
analytics/log/ Returned
unregister-GCM Sent
unregister-GCM Returned
analytics/log/ Sent
analytics/log/ Returned
verify Sent
verify Returned

看这里:

https://developer.android.com/reference/android/os/AsyncTask.html

When first introduced, 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. Starting with HONEYCOMB, tasks are executed on a single thread to avoid common application errors caused by parallel execution.

解决方案是:

If you truly want parallel execution, you can invoke executeOnExecutor(java.util.concurrent.Executor, Object[]) with THREAD_POOL_EXECUTOR.

api.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, "update-address/");

调用 execute 使 AsyncTasks 在单个后台线程上串行执行。

来自AsyncTask's documentation

Order of execution

When first introduced, 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. Starting with HONEYCOMB, tasks are executed on a single thread to avoid common application errors caused by parallel execution.

If you truly want parallel execution, you can invoke executeOnExecutor(java.util.concurrent.Executor, Object[]) with THREAD_POOL_EXECUTOR.

所有这些混乱是我停止使用 AsyncTask 的原因之一。

甚至我也想实现与您相同的目标并尝试了 AsyncTask。后来才知道Executors Thread Pool。我建议你使用 ThreadPool,它会同时发生,你可以管理正在创建的线程。

//Sample snapshot
ExecutorService pool = Executors.newCachedThreadPool();//or fixed thread pool

pool.execute(new Runnable() {
                @Override
                public void run() {
                    //Do your tasks
                }
            });

这对你有帮助,ThreadPoolExecutor