我知道已经有很多类似的AsyncTask
问题,但在我看来,有些事情是非常不寻常的,或者我错过了什么!
由于AsyncTask
不允许多次运行。我用new B().execute();
调用它,所以它应该在每次运行时创建一个单独的实例!正确?
问题是在创建并执行B类之后,第二次用户调用startBClass()
方法时它不会工作(只是打开对话框,但实际工作没有发生)。
我刚调试代码并意识到在Dialog关闭后,Thread仍然在后台运行。在Dialog关闭时停止后台线程的正确方法是什么? - 由于我正在关闭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();
}
}
}
答案 0 :(得分:1)
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
曾在哪里使用过?