-3

出于某种原因,我的调用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;
    }
}
4

2 回答 2

1

来自医生的

要使此类正常工作,必须遵循一些线程规则:

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

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

new ConnectTask().execute(params);
于 2013-05-02T08:29:57.387 回答
0

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

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

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

试试看是否有帮助,否则你应该分享错误或日志,以便我们解决问题:)

于 2013-05-02T08:31:24.257 回答