在执行以下代码时,我希望能够阻止它运行,即使它已经完成了一半。例如,如果我有一个boolean x = true;
,那么我想向这个线程/类发送一些stop(ReadJSONFeedMainTask);
命令之王。我想取消所有内容,甚至取消onPostExecute()
中可能发生的事情。我怎么能这样做?
这是我的代码:
private void doStuff() {
new ReadJSONFeedMainTask().execute(urlString);
}
private class ReadJSONFeedMainTask extends AsyncTask<String, Void, String> {
protected String doInBackground(String... urls) {
return Helper.readJSONFeed(urls[0]);
}
protected void onPostExecute(String result) {
try {
dictItems = new ArrayList<HashMap<?, ?>>();
JSONArray jsonArray = new JSONArray(result);
Log.i("JSON", "Number of items in feed: " + jsonArray.length());
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
HashMap<String, String> map = new HashMap<String, String>();
Iterator<?> it = jsonObject.keys();
while (it.hasNext())
{
// do a bunch of time consuming stuff
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
答案 0 :(得分:2)
要取消任务,请执行asyncTaskVariable.cancel()。如果它已经在onPostExecute中,它将不得不完成它 - 你在UI线程上并且无法杀死它。你可以做的最好是设置一个变量来告诉它终止(当然是从另一个线程),并让它定期检查该变量,如果它的设置则返回。
答案 1 :(得分:2)
当x为真时跳过;
while (it.hasNext() && x == false) // where x is your skip boolean
{
// do a bunch of time consuming stuff
}
并在您要终止的任何其他方法中执行类似操作。
它比在流动中终止它更安全,因为这可能导致异常行为。
答案 2 :(得分:2)
你应该致电
asyncTaskVariable.cancel( true );
这将迫使asynctask停止。
但是,你应该知道它不会立即停止。
如果线程正在等待IO输入,它将处于“阻塞的io状态”。然后它不会停止。如果您无法控制此Helper方法中发生的情况,则无法更改任何内容。但是如果你拥有它,那么你可以遍历输入流并每次读取多个字节(使用缓冲区)。这将为您提供阻止三人的机会。为此做点什么
int readBytes = 0;
while( readBytes != -1 && !Thread.interrupted ) {
readBytes = bufferedReader.read( buffer );
if( readBytes >0 ) {
stringBuilder.append( buffer, 0, readBytes );
}
}
使用interrupted
标志,当你的asynctask被取消时,你将能够停止你的线程。
您应该考虑不使用AsyncTask
进行网络操作。它们专为短期生活而设计。
AsyncTask旨在成为Thread和Handler的辅助类 并不构成通用的线程框架。 AsyncTasks 理想情况下应该用于短期操作(几秒钟的时间) 大多数。)如果你需要保持线程长时间运行, 强烈建议您使用提供的各种API java.util.concurrent pacakge如Executor,ThreadPoolExecutor和 FutureTask。
另一种方法是使用Android服务,就像使用RoboSpice库一样。
答案 3 :(得分:1)
为了做到这一点,你需要保留对你班级的引用。例如......
private ReadJSONFeedMainTask foo;
private void doStuff() {
foo = new ReadJSONFeedMainTask();
foo.execute(urlString);
}
然后,当你有中断事件时,你可以打电话
foo.cancel(true);
true参数表示立即中断。
编辑我没有注意到你在postexecute中放置了长跑任务。正如gabe正确提到的,即使cancel()也无法帮助你。您需要重构代码以将长运行任务放在doInBackground
方法中,以便它可以立即取消,除了如上所述保持对它的引用。