我知道已经有很多类似的AsyncTask
问题,但是就我而言,这是非常不寻常的,还是我错过了某些事情!
因为AsyncTask
不允许多次运行。我用new B().execute();
称呼它,所以它应该在每次运行时创建一个单独的实例!对?
问题是在B类创建并执行一次之后,它在用户第二次调用startBClass()
方法时将无法工作(只需打开对话框,但实际工作并未进行)。
我只是调试了代码,意识到关闭对话框之后,线程仍在后台运行。对话框关闭时停止后台线程的正确方法是什么? -而且由于我要关闭B类中的第一个Dialog并创建B类的另一个实例,所以为什么第二个不起作用?多个AsyncTasks不能并行运行吗?
我简化了类以更容易理解我在尝试什么:
public class A {
/* Is called when user clicks a button */
private void startBClass() {
new B().execute();
}
/* Opens a Dialog with a countdown TextView (works first call only) */
private class B extends AsyncTask<Void, Integer, Void> {
private int secondsPassed = 0;
private double totalToPay = 0;
private Dialog dialog;
private TextView tvCost;
private Button dialogBtn;
@Override
protected void onPreExecute() {
super.onPreExecute();
dialog = new Dialog(ConfigurationActivity.this);
dialog.setCancelable(true);
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.setContentView(R.layout.dialog);
dialog.setCanceledOnTouchOutside(false);
dialog.setOnCancelListener(new OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
onPostExecute(null);
}
});
tvCost = (TextView) dialog.findViewById(R.id.textCounter);
dialogBtn = (Button) dialog.findViewById(R.id.button1);
dialogBtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
dialog.cancel();
}
});
dialog.show();
}
@Override
protected Void doInBackground(Void... arg0) {
while(true){
publishProgress(secondsPassed++);
SystemClock.sleep(1000);
}
}
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
totalToPay = 12.00;
tvCost.setText(totalToPay + " USD");
}
@Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
final AlertDialog alert = new AlertDialog.Builder(ConfigurationActivity.this).create();
alert.setTitle("Information");
alert.setMessage("You should pay about " + totalToPay + " USD.");
alert.setButton("OK", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface alertDialog, int which) {
alertDialog.dismiss();
}
});
alert.show();
}
}
}
最佳答案
dialog.setOnCancelListener(new OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
onPostExecute(null);
}
});
不好根据the docs:
不要手动调用onPreExecute(),onPostExecute(Result),doInBackground(Params ...),onProgressUpdate(Progress ...)。
最后,我将更改上面的代码以及
doInBackground()
中的while循环。 protected Void doInBackground(Void... arg0) {
while(running){
publishProgress(secondsPassed++);
SystemClock.sleep(1000);
}
}
running
是在true
中设置为onPreExecute()
的布尔值。要结束时将其设置为false
。然后,您的循环将退出,并且onPostExecute()
将被正确调用。旁注:
secondsPassed
曾经在哪里使用?