1

我知道已经有很多类似的AsyncTask问题,但就我而言,有些事情很不寻常,或者我错过了什么!?

由于AsyncTask不允许多次运行。我用它来调用它,new B().execute();所以它应该在每次运行时创建一个单独的实例!?正确的?

问题是在 B 类创建并执行一次后,用户第二次调用该startBClass()方法时它不会工作(只是打开对话框,但实际工作没有发生)。

我刚刚调试了代码,发现Dialog关闭后,线程还在后台运行。对话框关闭时停止后台线程的正确方法是什么?- 由于我关闭 B 类中的第一个对话框并创建 B 类的另一个实例,为什么第二个不工作?多个 AsyncTask 不能并行运行!?

我简化了课程以便于理解我正在尝试的内容:

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();
       }
   }
}
4

1 回答 1

1
dialog.setOnCancelListener(new OnCancelListener() {
    @Override
    public void onCancel(DialogInterface dialog) {
        onPostExecute(null);
    }
});

这不好。根据文档

不要手动调用 onPreExecute()、onPostExecute(Result)、doInBackground(Params...)、onProgressUpdate(Progress...)。

为了结束它,我将同时更改上面的代码和doInBackground().

   protected Void doInBackground(Void... arg0) {
       while(running){
           publishProgress(secondsPassed++);
           SystemClock.sleep(1000);
       }
   }

runningtrue是您在 中设置的布尔值onPreExecute()。将其设置为false您想要结束它的时间。然后你的循环将退出并被onPostExecute()正确调用。

旁注:secondsPassed曾经在哪里使用过?

于 2013-02-28T02:47:12.383 回答