-1

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

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
4

3 回答 3

1

看这里:

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

首次引入时,AsyncTask 在单个后台线程上串行执行。从 DONUT 开始,这被更改为允许多个任务并行运行的线程池。从 HONEYCOMB 开始,任务在单个线程上执行,以避免并行执行导致的常见应用程序错误。

解决方案是:

如果你真的想要并行执行,你可以使用 THREAD_POOL_EXECUTOR 调用 executeOnExecutor(java.util.concurrent.Executor, Object[])。

api.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, "update-address/");
于 2018-04-06T15:29:48.390 回答
1

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

AsyncTask 的文档中

执行顺序

首次引入时,AsyncTask 在单个后台线程上串行执行。从 DONUT 开始,这被更改为允许多个任务并行运行的线程池。从 HONEYCOMB 开始,任务在单个线程上执行,以避免并行执行导致的常见应用程序错误。

如果你真的想要并行执行,你可以使用 THREAD_POOL_EXECUTOR 调用 executeOnExecutor(java.util.concurrent.Executor, Object[])。

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

于 2018-04-06T15:30:26.593 回答
0

甚至我也想实现与您相同的目标并尝试了 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

于 2018-04-06T16:32:50.543 回答