Android 异步任务 waiting/queued
Android AsyncTask waiting/queued
我有一个 class 扩展一个 AsyncTask,它可以将消息发送到 WCF Web 服务。一个接一个的简单消息可以正常工作,但是如果我在一个需要 30 秒才能完成的新线程上发送一条消息,然后在中途我发送一个快速请求它不会执行 AsyncTask 直到长的请求返回。
我认为 AsyncTask 的整个想法是这两条消息会 运行 在不同的线程上,因此不会堆叠?
这是我的代码:
private class RunnableTask extends AsyncTask<RunnableObj, RunnableObj, RunnableObj> {
@Override
protected RunnableObj doInBackground(RunnableObj... params) {
try {
if (params[0].requestBody != (null)) {
params[0].request.body(new JSONObject(params[0].requestBody));
}
params[0].request.asVoid();
return params[0];
}
catch (Throwable e) {
params[0].handler.onFailure(e);
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(RunnableObj runnableObj) {
super.onPostExecute(runnableObj);
runnableObj.handler.onSuccess();
}
}
这是我上面的AsyncTask。
public void put(final String urlStr, final String requestBody, final HttpResponseHandler httpResponseHandler) {
RunnableObj obj = new RunnableObj();
obj.handler = httpResponseHandler;
obj.request = webb.put(urlStr)
.header(ServiceConstants.SessionTokenHeader, MyApplication.getSessionToken())
.ensureSuccess();
obj.requestBody = requestBody;
new RunnableTask().execute(obj);
}
这是我用来调用异步的方法。
正如您在我用来调用服务的方法中看到的那样,我每次都初始化一个新的 RunnableTask 实例。
它的表现如何:
长请求会转到web服务并启动30秒的服务
10 秒后,我的快速小 PUT 创建了它的对象,然后调试器显示的最后一件事是 "new RunnableTask().execute(obj);" 行上的断点,然后它就消失了。
20 秒后,我的 RunnableTasks doInBackground 方法的第一行将命中并执行 PUT。
有人可以帮忙吗?或者至少告诉我我正在做一些非常愚蠢的事情..
根据 AsyncTask Docs:
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.
如您所见,AsyncTasks 目前仅在单个后台线程上运行,这意味着多个排队的任务将不得不一个接一个地触发。如果您想执行并发任务,则需要按照上述说明进行操作。
你可以使用executeOnExecutor执行多个AsyncTask
if( Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB ) {
new MyAsyncTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
} else {
new MyAsyncTask().execute();
}
有关更多信息,请查看 AsyncTask documentation
我有一个 class 扩展一个 AsyncTask,它可以将消息发送到 WCF Web 服务。一个接一个的简单消息可以正常工作,但是如果我在一个需要 30 秒才能完成的新线程上发送一条消息,然后在中途我发送一个快速请求它不会执行 AsyncTask 直到长的请求返回。
我认为 AsyncTask 的整个想法是这两条消息会 运行 在不同的线程上,因此不会堆叠?
这是我的代码:
private class RunnableTask extends AsyncTask<RunnableObj, RunnableObj, RunnableObj> {
@Override
protected RunnableObj doInBackground(RunnableObj... params) {
try {
if (params[0].requestBody != (null)) {
params[0].request.body(new JSONObject(params[0].requestBody));
}
params[0].request.asVoid();
return params[0];
}
catch (Throwable e) {
params[0].handler.onFailure(e);
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(RunnableObj runnableObj) {
super.onPostExecute(runnableObj);
runnableObj.handler.onSuccess();
}
}
这是我上面的AsyncTask。
public void put(final String urlStr, final String requestBody, final HttpResponseHandler httpResponseHandler) {
RunnableObj obj = new RunnableObj();
obj.handler = httpResponseHandler;
obj.request = webb.put(urlStr)
.header(ServiceConstants.SessionTokenHeader, MyApplication.getSessionToken())
.ensureSuccess();
obj.requestBody = requestBody;
new RunnableTask().execute(obj);
}
这是我用来调用异步的方法。
正如您在我用来调用服务的方法中看到的那样,我每次都初始化一个新的 RunnableTask 实例。
它的表现如何:
长请求会转到web服务并启动30秒的服务
10 秒后,我的快速小 PUT 创建了它的对象,然后调试器显示的最后一件事是 "new RunnableTask().execute(obj);" 行上的断点,然后它就消失了。
20 秒后,我的 RunnableTasks doInBackground 方法的第一行将命中并执行 PUT。
有人可以帮忙吗?或者至少告诉我我正在做一些非常愚蠢的事情..
根据 AsyncTask Docs:
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.
如您所见,AsyncTasks 目前仅在单个后台线程上运行,这意味着多个排队的任务将不得不一个接一个地触发。如果您想执行并发任务,则需要按照上述说明进行操作。
你可以使用executeOnExecutor执行多个AsyncTask
if( Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB ) {
new MyAsyncTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
} else {
new MyAsyncTask().execute();
}
有关更多信息,请查看 AsyncTask documentation