Android中的AsyncTask启动但不处理

时间:2013-02-28 02:16:36

标签: android multithreading android-asynctask

我知道已经有很多类似的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();
       }
   }
}

1 个答案:

答案 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曾在哪里使用过?