使用 AsyncTask [Android] 设置超时函数

Set timeout function with AsyncTask [Android]

在我的例子中,我想要按下按钮并获得超时处理。单击按钮时,它将使用 Web 服务验证 accNo,如果验证(ProgressDialog)超过 5 秒,它将停止并显示 alertDialog 以通知用户 "Timeout"。

但现在我不知道什么时候用 1 毫秒进行测试,从逻辑上讲,它会在 alertDialog 中暂停,直到被按下,但现在它会以毫秒为单位显示对话框,然后自动关闭并进入下一个 activity.这是我的代码:

@Override
protected void onCreate(final Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_information3);

btn_next.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (title.getText().toString().equals("INFO")) {
                InfoAsyncTask infoAsyncTask = new InfoAsyncTask();
                try {
                    infoAsyncTask.execute().get(1, TimeUnit.MILLISECONDS);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (ExecutionException e) {
                    e.printStackTrace();
                } catch (TimeoutException e) {
                    AlertDialog.Builder alertDialog = new AlertDialog.Builder(Information3.this);
                    alertDialog.setTitle(":: Error ::");
                    alertDialog.setMessage("Verify Timeout. Please try again.");

                    alertDialog.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            dialog.dismiss();
                        }
                    });
                    alertDialog.show();
                }
           }
       });
   }

private class InfoAsyncTask extends AsyncTask<Void, Void, String> {
    private String results;
    private ProgressDialog pDialog;
    private Object resultRequestSOAP;
    String accNo = et_accNo.getText().toString().trim();
    int timeout = 15000;

    @Override
    protected void onPreExecute() {
        pDialog = new ProgressDialog(Information3.this);
        pDialog.setMessage("Verifying...");
        pDialog.setIndeterminate(false);
        pDialog.setCancelable(true);
        pDialog.show();
        super.onPreExecute();
    }

    @Override
    protected String doInBackground(Void... params) {
        SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
        request.addProperty("Code", InfoCode);
        request.addProperty("AccNo", accNo);

        SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
        envelope.dotNet = true;
        envelope.setOutputSoapObject(request);
        HttpTransportSE androidHttpTransport = new HttpTransportSE(URL, timeout);
        androidHttpTransport.debug = true;

        try {
            androidHttpTransport.call(SOAP_ACTION, envelope);
            String requestDumpString = androidHttpTransport.requestDump;
            Log.d("request Dump: ", requestDumpString);
        } catch (Exception e) {
            e.printStackTrace();
        }
        try {
            resultRequestSOAP = envelope.getResponse();
            results = resultRequestSOAP.toString();
            Log.d("Output: ", results);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    protected void onPostExecute(String result) {
        if (resultRequestSOAP == null) {
            if (pDialog.isShowing()) {
                pDialog.dismiss();
            } else {
                AlertDialog.Builder alertDialog = new AlertDialog.Builder(Information3.this);

                alertDialog.setTitle(":: Error ::");
                alertDialog.setMessage("Connection error, please check your internet connection.");

                alertDialog.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.dismiss();
                    }
                });
                alertDialog.show();
                pDialog.dismiss();
            }
        } else {
            if (results.equals("false")) {
                AlertDialog.Builder alertDialog = new AlertDialog.Builder(Information3.this);

                alertDialog.setTitle(":: Warning ::");
                alertDialog.setMessage("Please fill in correct account number");

                alertDialog.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.dismiss();
                    }
                });
                alertDialog.show();
            } else if (et_billNo.getText().toString().trim().isEmpty()) {
                AlertDialog.Builder alertDialog = new AlertDialog.Builder(Information3.this);

                alertDialog.setTitle(":: Warning ::");
                alertDialog.setMessage("Please fill in bill number");

                alertDialog.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.dismiss();
                    }
                });
                alertDialog.show();
            } else if (et_amountNo.getText().toString().trim().isEmpty() || Integer.parseInt(et_amountNo.getText().toString().trim()) <= 0) {
                AlertDialog.Builder alertDialog = new AlertDialog.Builder(Information3.this);

                alertDialog.setTitle(":: Warning ::");
                alertDialog.setMessage("Please fill in amount");

                alertDialog.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.dismiss();
                    }
                });
                alertDialog.show();
            } else if (results.equals("true")) {
                Title = title.getText().toString();
                String value1 = et_accNo.getText().toString().trim();
                String value2 = et_billNo.getText().toString().trim();
                int value3 = Integer.parseInt(et_amountNo.getText().toString().trim());

                addSearchInput(value1);
                addSearchInput(value2);
                addSearchInput(String.valueOf(value3));

                Intent intent = new Intent(Information3.this, confirmation3.class);
                intent.putExtra("name", Title);
                intent.putExtra("value1", value1);
                intent.putExtra("value2", value2);
                intent.putExtra("value3", value3);
                startActivity(intent);
            } else {
                super.onPreExecute();
            }
            pDialog.dismiss();
        }
    }
}

get() 方法会阻塞 UI 线程,我猜你不想要这个。

您应该在 doInBackground 中实现取消机制并通过超时调用 AsyncTask.cancel() [像那样](https://developer.android.com/reference/android/os/Handler.html#postDelayed(java.lang.Runnable, long))

final Handler handler = new Handler();
    handler.postDelayed(new Runnable() {
      @Override
      public void run() {
        AsyncTask.cancel();
      }
    }, 1);

注意 AsyncTask 有很多问题,请查看我的 article