单击按钮时无法取消异步任务

时间:2015-06-15 16:26:28

标签: android android-asynctask

我正在尝试在弹出框的按钮单击上取消/结束异步任务。但是,当我单击按钮时,不会调用onCancelled()方法。有人可以帮我这个吗?以下是我的代码:

public AuthenticationAsync(Context context, final String rid) {
    this.rid = rid;

    alertDialog = new AlertDialog.Builder(context).create();
    alertDialog.setTitle("Information");
    alertDialog.setMessage("RaspberryPi Validated");
    alertDialog.setButton(AlertDialog.BUTTON_NEUTRAL, "OK",
            new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int which) {
                    cancel(true); //Cancelling async task on button click
                    dialog.dismiss();
                }
            });
}


@Override
protected Object doInBackground(Object[] params) {
    String metricData = String.valueOf(kuraPayload.getMetric("data"));
    if (metricData.isEmpty()) 
        subResponse = false;
}

@Override
protected void onCancelled() {
    Log.d("Async","cancelled");  //not being called
}

@Override
protected void onPostExecute(Object o) {
    if (subResponse) {
        asyncHttpClient = new AsyncHttpClient();
        asyncHttpClient.get(WSConstants.ADD_RPI_WS + MQTTFactory.getRaspberryPiById(), new AsyncHttpResponseHandler() {

            @Override
            public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {
                Toast.makeText(ActivityContexts.getMainActivityContext(), "RaspberryPi Validated", Toast.LENGTH_LONG).show();
                alertDialog.show();
            }

    } 
}
}

2 个答案:

答案 0 :(得分:1)

看起来它永远不会进入onCancelled(),因为您实际上是在alertDialog.show()中呼叫onPostExecute()。由于doInBackground()已经完成,因此没有任何内容可以取消。

cancel()方法是在执行doInBackground()方法期间调用的,这是在后台线程上运行的唯一方法。

请注意,即使在执行cancel()期间调用doInBackground(),也不会立即停止执行该方法。您应该定期检查isCancelled(),如果它返回true,则退出方法。

doInBackground()完成后,如果调用了cancel(),则会调用onCancelled()而不是onPostExecute()

这是一个基于您的代码的非常简单的测试:

public class AuthenticationAsync extends AsyncTask {

    AlertDialog alertDialog;
    String rid;

    public AuthenticationAsync(Context context, final String rid) {
        this.rid = rid;

        alertDialog = new AlertDialog.Builder(context).create();
        alertDialog.setTitle("Information");
        alertDialog.setMessage("RaspberryPi Validated");
        alertDialog.setButton(AlertDialog.BUTTON_NEUTRAL, "OK",
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        cancel(true); //Cancelling async task on button click
                        dialog.dismiss();
                    }
                });
    }

    @Override
    protected void onPreExecute(){
        //for testing, showing the dialog before the background Thread starts
        alertDialog.show();
    }

    @Override
    protected Object doInBackground(Object[] params) {
       //cycle forever until the user clicks OK
       while (true){
           try {
               Thread.sleep(1000);
           } catch (InterruptedException e) {
               e.printStackTrace();
           }
           //Check if user clicked OK in the dialog
           if (isCancelled()){
               //Exit the method if the user dismissed the dialog
               return null;
           }
       }
    }

    @Override
    protected void onCancelled() {
        Log.d("Async", "cancelled");  //this is called now
        Toast.makeText(MainActivity.this, "cancelled", Toast.LENGTH_LONG).show();
    }

    @Override
    protected void onPostExecute(Object o) {
        Toast.makeText(MainActivity.this, "postExecute", Toast.LENGTH_LONG).show();
    }
}

<强>结果:

执行doInBackground()期间显示对话框:

dialog shown

单击“确定”后,将调用onCancelled()

onCancelled

答案 1 :(得分:0)

@yanchenko回答了类似的事情 - &gt; Ideal way to cancel an executing AsyncTask

您可以使用一个ProgressDialog并将此对话框设置为Cancelable并设置CancelListener。