【问题标题】:How to Handle connection timeout in async task如何处理异步任务中的连接超时
【发布时间】:2017-08-16 04:42:08
【问题描述】:

我有一个尚未解决的问题,我需要帮助。

当网速慢时应用程序崩溃。如何在 asyntask 中检查连接超时。

我制作了一个有时会连接到 Web 服务以获取数据的应用,我使用异步任务来完成此操作

当用户可以选择是否要重试或取消时,我想在连接超时时发出警报对话框,如果他们选择重试,它将再次尝试连接

 public class login extends AsyncTask<Void,Void,Void> {

    InputStream ins;
    String status, result, s = null, data = "",js;
    int ss;
    int responseCode;

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        pdlg.setTitle("Checking");
        pdlg.setMessage("Please wait");
        pdlg.setCancelable(false);
        pdlg.show();
    }

    @Override
    protected Void doInBackground(Void... params) {
        StringBuilder sb = new StringBuilder();
        ArrayList al;
        try {
            URL url = new URL("http://....login.php");
            String param = "username=" + uname + "&password=" + pass;
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setRequestMethod("POST");
            connection.setConnectTimeout(15000);
            connection.setReadTimeout(15000);
            connection.setDoInput(true);
            connection.setDoOutput(true);

            OutputStream os = connection.getOutputStream();
            BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(os, "UTF-8"));
            bw.write(param);
            bw.flush();
            bw.close();

            responseCode = connection.getResponseCode();
            if (responseCode == HttpURLConnection.HTTP_OK) {
                BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream()));
                String line = "";
                while ((line = br.readLine()) != null) {
                    sb.append(line + "\n");
                }
            }
            data = sb.toString();
            JSONObject json = new JSONObject(data);

            status=json.getString("Status");//{"Login Status":"Success","Receipt Details":"No data available"}

           // js=json.getString("Login");//{"Login":"Failed"}



        } catch (MalformedURLException e) {
            Log.i("MalformedURLException", e.getMessage());
        } catch (IOException e) {
            Log.i("IOException", e.getMessage());
        } catch (JSONException e) {
            Log.i("JSONException", e.getMessage());
        }

        return null;
    }

    protected void onPostExecute(Void result) {
        super.onPostExecute(result);

        String status1=status.trim();


      if (status1.equals("Success")) {
    Toast.makeText(getApplicationContext(), "Login Succes  !!", Toast.LENGTH_SHORT).show();

          Intent i = new Intent(Login.this, Home.class);
          startActivity(i);
            finish();
          SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
          SharedPreferences.Editor editor = sharedPreferences.edit();
          editor.putBoolean("first_time", false);
          editor.putString("userrname", uname);
          editor.putString("password",pass);
          editor.apply();
          Toast.makeText(getApplicationContext(),"welcome : "+uname,Toast.LENGTH_LONG).show();

      }

else {
    Toast t=Toast.makeText(Login.this, "Username or Password is Incorrect", Toast.LENGTH_LONG);
          t.setGravity(Gravity.BOTTOM,0,0);
                        t.show();
}

        pdlg.dismiss();


    }



   }

【问题讨论】:

    标签: android connection-timeout


    【解决方案1】:

    你可以使用getErrorStream()

    HttpURLConnection connection = (HttpURLConnection) url.openConnection();
    InputStream inp;
    
    // if some error in connection 
     inp = connection.getErrorStream();
    

    查看this答案了解更多详情..

    根据doc返回

    如果有错误流,如果没有错误,则返回 null, 连接未连接或 服务器没有发送有用的数据

    .

    【讨论】:

      【解决方案2】:

      使用这两个 catch 块来处理 ConnectionTimeOut 和 socketTimeOut 异常

              catch (SocketTimeoutException bug) {
                  Toast.makeText(getApplicationContext(), "Socket Timeout", Toast.LENGTH_LONG).show();
              } 
              catch (ConnectTimeoutException bug) {
                  Toast.makeText(getApplicationContext(), "Connection Timeout", Toast.LENGTH_LONG).show();
              } 
      

      【讨论】:

        【解决方案3】:

        对于连接超时,在您的 catch 块中添加 SocketTimeoutException 并使其崩溃,因为没有空检查,您正在尝试修剪 onPostExecute 中的字符串

        你应该这样做,并在使用状态之前检查

        if(TextUtil.isEmpty(status)) {
           pdlg.dismiss();
           // We are getting empty response
           return;
        }
        String status1=status.trim();
        

        【讨论】:

          【解决方案4】:

          您可以在代码中捕获连接超时异常,然后根据您的要求设置状态并在 onPostExecute 中检查该状态以显示警报对话框

          try {
                      URL url = new URL("http://....login.php");
                      String param = "username=" + uname + "&password=" + pass;
              // Your URL connection code here
          catch (ConnectTimeoutException e) {
                  Log.e(TAG, "Timeout", e);
                  status="timeout"
              } catch (SocketTimeoutException e) {
                  Log.e(TAG, " Socket timeout", e);
                  status="timeout"
              }
          

          onPostExecute

          if (status.equals("timeout")) {
              // Show Alert Dialog.
          }
          

          【讨论】:

            【解决方案5】:

            您之前尝试做的事情是在一些很棒的网络库中完成的。因此,我敦促您使用 widley 使用的网络库之一。 凌空抽射。

            或者如果你想了解你可以检查响应状态(或者状态码应该是 408。我猜是连接超时)如果它会返回“连接超时”那么你可以调用你的代码到 http 客户端再次执行您的任务,您也可以添加重试次数以尝试 2-3 次,然后放弃并将响应发送到 onpostexecute 方法。

            希望这会有所帮助。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2016-10-01
              • 2020-07-08
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多