AsyncTask.cancel只能运行一次

时间:2013-05-02 08:10:14

标签: android android-asynctask

出于某种原因,我对AsyncTask.cancel的调用只能工作一次,即对于任务的第一个实例,并且再也不会。第一个任务取消精美并点击onCancelled方法。所有其他人似乎都忽略了cancel()来电并最终进入onPostExecute

任务从服务执行:

public class ZitFtpService extends Service implements ZitFtpServiceInterface
{
//Blah blah

public void connect(String server, int port)
{
    if(!isConnecting){
        isConnecting = true;
        ConnectTask task = new ConnectTask();
        task.execute(server, String.valueOf(port));
    }
    }
    //Blah blah blah

正如您所看到的,每次都是一个新实例。我不明白为什么第一个会与后续的不同。 AsyncTask是一个私人内部类:

private class ConnectTask extends AsyncTask<String, String, Boolean> {

    @Override
    protected Boolean doInBackground(String... params) {

        boolean result = false;

        try {
            publishProgress(
                    "start", "Connecting to "+ params[0] + ":" + params[1]);
            Log.v("ZIT", params[0] + " " + params[1] + " " + params.length);
            conn.connect(params[0], Integer.valueOf(params[1]), 1000);
            result = true;
            } catch (NumberFormatException e) {
            Log.e("ZIT", e.getMessage());
        } catch (IOException e) {
                failMessage = e.getMessage();
                e.printStackTrace();
            } 
        return Boolean.valueOf(result);
    }

    private void cancelConnect()  {
        try {
            conn.disconnect();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            conn = new ZMobileFTPImpl();
        }

        if(!(dialog==null)) {
            dialog.dismiss();
        }
    }

    @Override
    protected void onCancelled() {
        Log.v("ZIT", "I was cancelled.");
        isConnecting = false;
    } 

    @Override
    protected void onProgressUpdate(String... values) {

        if(dialog == null) {
            dialog = new ProgressDialog(progressActivity);
            dialog.setCancelable(true);
            dialog.setOnCancelListener(new OnCancelListener() {

                @Override
                public void onCancel(DialogInterface dialog) {
                    ConnectTask.this.cancel(true);
                    cancelConnect();
                    dialog.dismiss();

                }
            });
            dialog.setButton(DialogInterface.BUTTON_NEGATIVE, "Cancel", 
                    new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    dialog.cancel();
                }
            });
        }

        dialog.setMessage(values[1]);
        dialog.setCancelable(true);
        dialog.show();  
    }

    @Override
    protected void onPostExecute(Boolean result) {

        dialog.dismiss();
        if(!result) {
            AlertDialog.Builder builder = 
                    new AlertDialog.Builder(progressActivity);
            builder.setMessage(failMessage).setTitle("Error");
            failMessage = "";
            builder.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
                   public void onClick(DialogInterface dialog, int id) {
                       dialog.dismiss();
                   }
               });
            AlertDialog failDialog = builder.create();
            failDialog.show();
        }

        isConnecting = false;
    }
}

2 个答案:

答案 0 :(得分:1)

<强> From Doc's

此类必须遵循一些线程规则才能正常工作:

  • 必须在UI线程上加载AsyncTask类。这是从JELLY_BEAN开始自动完成的。
  • 必须在UI线程上创建任务实例。
  • 必须在UI线程上调用
  • execute(Params...)
  • 请勿手动拨打onPreExecute(), onPostExecute(Result), doInBackground(Params...), onProgressUpdate(Progress...)
  • 任务只能执行一次(如果尝试第二次执行,则会抛出异常。)

因此,您可以通过每次创建新实例多次调用AsyncTask,如

new ConnectTask().execute(params);

答案 1 :(得分:0)

这是故意的,因为你只能执行一次AsyncTask实例,你可以多次运行task.execute ......

无论如何,我相信您忘记在以下覆盖中添加super.onCancelled:

@Override
public void onCancelled() {
    //...
    super.onCancelled();
}

尝试这是否有帮助,否则您应该共享错误或日志,以便我们可以解决这个问题:)