我需要取消我的asyncthread。在我的应用程序中,我正在做一些繁重的计算,我想让用户能够取消计算(然后重试)。我在论坛上看到,你不能只是停止它正在做什么的任务,你需要在你的DoinBackground代码中检查任务是否为isCancelled = true。但那对我不起作用。
任务本身运行良好,如果我让它自行结束,它会输出正确的数据。
在我的应用程序中,我首先调用函数naredi_pdf_start(view),然后当任务运行时,如果我调用close_pdf1(view),它会给我一个错误。(我正在更改视图,app无法找到我的pdf_text1 Textview当调用publishProgress- null指针异常时)。我真的不知道如何使用task.cancel(true)方法(在我的例子中:start_pdf.cancel(true)))。
这是我的代码:
String progress_pdf;
naredi_pdf start_pdf;
public void naredi_pdf_start(View view) {
start_pdf=new naredi_pdf();
start_pdf.execute();
}
public void close_pdf1(View view) {
if(start_pdf!=null) {
Log.v("not null","not null");
start_pdf.cancel(true);
setContentView(R.layout.other_view); //This is where
//I don't have TextView pdf_text1
}
}
private class naredi_pdf extends AsyncTask<Void, String, Void> {
protected Void doInBackground( Void... ignoredParams ) {
progress_pdf="Calculating Statistical Data";
//A LOT OF CODING
for(int i = 0; i < 1; i++) {
if(isCancelled()) {
break;
}
else {
publishProgress("Calculating team statistics");
}
}
//MORE OF CODING
for (int i = 0; i < 1; i++) {
if (isCancelled()) {
break;
}
else {
publishProgress("Calculating player's BIO");
}
}
//MORE OF CODING
for (int i = 0; i < 1; i++) {
if (isCancelled()) {
break;
}
else {
publishProgress("Calculating player's individual performance");
}
}
return null;
}
protected void onPostExecute( Void array ) {
//saving to database
}
protected void onProgressUpdate(String... values) {
progress_pdf=values[0]+"\n"+progress_pdf;
if (isCancelled()) {
}
else {
TextView pdf_text1 = (TextView) findViewById (R.id.pdf_text1);
pdf_text1.setText(progress_pdf);
// dialog(view);
}
}
}
答案 0 :(得分:2)
return
语句取消执行doInBackground方法,而不是break
。
答案 1 :(得分:2)
您的问题不在于您无法取消AsyncTask
。您可能会收到NullPointerException
,因为在setContentView()
成功之前,您对AsyncTask.cancel()
的来电已经过去了。调用onProgressUpdate()
只会发现布局现在已更改且View
没有id=R.id.pdf_text1
!
来自AsyncTask的文档。
可以通过调用cancel(boolean)随时取消任务。调用此方法将导致后续调用isCancelled()返回true。调用此方法后,将在doInBackground(Object [])返回后调用onCancelled(Object)而不是onPostExecute(Object)。为确保尽快取消任务,应始终定期从doInBackground(Object [])检查isCancelled()的返回值(如果可能)(例如在循环内)。
由于onCancelled()
在UI线程上运行,并且您确定不会发生对onProgressUpdate()
的后续调用,因此它是调用setContentView()
的好地方。
覆盖onCancelled()
AsyncTask
private class naredi_pdf extends AsyncTask<Void, String, Void> {
protected Void doInBackground( Void... ignoredParams ) { // YOUR CODE HERE}
protected void onPostExecute( Void array ) { // YOUR CODE HERE}
protected void onProgressUpdate(String... values) {// YOUR CODE HERE}
// ADD THIS
@Override
protected void onCancelled() {
// Do not call super.onCancelled()!
// Set the new layout
setContentView(R.id.other_layout);
}
}
更改close_pdf1()
public void close_pdf1(View view) {
if(start_pdf!=null) {
Log.v("not null","not null");
start_pdf.cancel(true);
}
}
你应该有AsyncTask
在取消时自动更改你的布局。希望您不应该遇到任何NullPointerException
。但是没有尝试过代码:)
修改强>
如果您觉得有意思,请按照Rezooms的建议使用return
。
for(int i = 0; i < 1; i++) {
if(isCancelled()) {
return null;
}
.
.
.
}
答案 2 :(得分:0)
是Canceled是AsyncTask类的专有方法。
您应该在扩展类上定义一个私有布尔属性,执行类似这样的操作
private class myAsyncTask extends AsyncTask<Void, String, Void> {
private boolean isTaskCancelled = false;
public void cancelTask(){
isTaskCancelled = true;
}
private boolean isTaskCancelled(){
return isTaskCancelled;
}
protected Void doInBackground( Void... ignoredParams ) {
//Do some stuff
if (isTaskCancelled()){
return;
}
}
protected void onPostExecute( Void array )
{
//Do something
}
protected void onProgressUpdate(String... values)
{
//Do something
}
}