【发布时间】:2023-10-13 21:06:02
【问题描述】:
好的,这是我第一次使用 Java 中的异步和队列,所以代码可能不是最好的......无论如何:
我想编写一个运行 HTTP 请求的 AsyncTask,如果用户在 Async 运行时发送更多请求,它会将请求添加到队列中,然后异步执行每个请求。
private Queue<String> pasteQueue = new LinkedList<String>();
private boolean running = false;
我创建了这个方法来管理每个请求:
public void postPaste(String title, String code, String language, String scadenza, int visibility)
{
String dev_key = "";
StringBuilder url = new StringBuilder();
url.append("http://pastebin.com/api/api_post.php?api_option=paste")
.append("&api_paste_private=").append(visibility)
.append("&api_paste_name=").append(title)
.append("&api_paste_expire_date=").append(scadenza)
.append("&api_paste_format=").append(language)
.append("&api_dev_key=").append(dev_key)
.append("&api_paste_code=").append(code);
Log.d(MyActivity.DEBUG_TAG, "URL: " + url.toString());
// Todo: implement api_user_key
Log.d(MyActivity.DEBUG_TAG, "running == " + running);
if (running)
{
Log.d(MyActivity.DEBUG_TAG, "PASTE added to queue");
pasteQueue.add(url.toString());
}
else
{
Log.d(MyActivity.DEBUG_TAG, "Execute async");
execute(url.toString());
}
}
为了检查异步是否正在运行,我创建了一个布尔变量(正在运行),当调用 doInBackground 时它设置为“true”,当 onPostExecute 完成时设置为 false。
这是我的 doInBackground 方法:
@Override
protected String doInBackground(String... params) {
Log.d(MyActivity.DEBUG_TAG, "doInBackground");
if (params[0] == null)
{
return null;
}
running = true;
HttpClient httpClient = new DefaultHttpClient();
HttpResponse response;
String finalResponse = null;
try
{
response = httpClient.execute(new HttpGet(params[0]));
StatusLine statusLine = response.getStatusLine();
if (statusLine.getStatusCode() == HttpStatus.SC_OK)
{
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
response.getEntity().writeTo(outputStream);
outputStream.close();
finalResponse = outputStream.toString();
}
else
{
response.getEntity().getContent().close();
}
} catch (ClientProtocolException e) {
// ToDo: Something
} catch (IOException e) {
// ToDo: Something
}
return finalResponse; //To change body of implemented methods use File | Settings | File Templates.
}
首先,我检查 params[0] 是否为 null(如果 pasteQueue.poll() 返回 null)然后我运行一个简单的 http 请求..
我放了完整的 doInBackground,因为问题可能出在 HTTP 请求中(我从未在 Android 中使用过 HTTP 函数,是的,我一般是 Android 新手。)
那么,onPosteExecute 就只有这个了:
@Override
protected void onPosteExecute(String s)
{
Log.d(MyActivity.DEBUG_TAG, "onPostExecute");
super.onPostExecute(s); //To change body of overridden methods use File | Settings | File Templates.
if (pasteQueue.size() > 0)
{
Log.d(MyActivity.DEBUG_TAG, "queue.size > 0, poll item");
execute(pasteQueue.poll());
}
running = false;
Log.d(MyActivity.DEBUG_TAG, "onPostExecute - fine");
}
(我删除了无用的代码)
我使用了一个运行 postPaste 的按钮,如果我再次按下该按钮(调用 onPostExecute),应用程序会因此崩溃:
Caused by: java.lang.IllegalStateException: 无法执行任务:任务已经执行过(一个任务只能执行一次)
11-30 18:06:50.608:错误/AndroidRuntime(2246):致命异常:主要 java.lang.IllegalStateException:无法执行活动的方法 在 android.view.View$1.onClick(View.java:3599) 在 android.view.View.performClick(View.java:4204) 在 android.view.View$PerformClick.run(View.java:17355) 在 android.os.Handler.handleCallback(Handler.java:725) 在 android.os.Handler.dispatchMessage(Handler.java:92) 在 android.os.Looper.loop(Looper.java:137) 在 android.app.ActivityThread.main(ActivityThread.java:5041) 在 java.lang.reflect.Method.invokeNative(Native Method) 在 java.lang.reflect.Method.invoke(Method.java:511) 在 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793) 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560) 在 dalvik.system.NativeStart.main(本机方法) 引起:java.lang.reflect.InvocationTargetException 在 java.lang.reflect.Method.invokeNative(Native Method) 在 java.lang.reflect.Method.invoke(Method.java:511) 在 android.view.View$1.onClick(View.java:3594) ... 11 更多 引起:java.lang.IllegalStateException:无法执行任务:任务已经执行(一个任务只能执行 一次) 在 android.os.AsyncTask.executeOnExecutor(AsyncTask.java:578) 在 android.os.AsyncTask.execute(AsyncTask.java:534) 在 com.revonline.pastebin.Pastebin.postPaste(Pastebin.java:65) 在 com.revonline.pastebin.MyActivity.sharePaste(MyActivity.java:132) ... 14 更多
有什么问题? AsyncTask 不适合这种情况?我应该使用普通线程代码吗?
我读过一个问题,其中有人说异步任务可能仍会运行 5 秒,但我认为这不是同一个问题..
【问题讨论】:
标签: java android asynchronous android-asynctask