如何在异步任务中处理连接超时问题

3

我有一个问题还没有解决,需要帮助。

当网络变慢时,应用程序会崩溃。如何在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();


    }



   }
5个回答

1
你想做的事情之前已经在一些出色的网络库中完成了。所以我建议你使用其中一个广泛使用的网络库:Volley。
或者,如果你想要理解,可以检查响应状态(或状态代码应该为408,我猜是连接超时),如果返回“连接超时”,那么你可以再次调用HTTP客户端来执行你的任务,你也可以添加重试计数器尝试2-3次,然后放弃并将响应发送到onpostexecute方法。
希望这可以帮到你。

1
请使用这两个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();
        } 

1
对于连接超时,请在catch块中添加SocketTimeoutException,而且你的应用崩溃了,因为在onPostExecute中尝试修剪字符串时没有进行空检查。
你应该像这样做,并在使用状态之前进行检查。
if(TextUtil.isEmpty(status)) {
   pdlg.dismiss();
   // We are getting empty response
   return;
}
String status1=status.trim();

1
你可以在代码中捕获连接超时异常,然后根据你的要求设置状态,并在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.
}

1
你可以使用getErrorStream()
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
InputStream inp;

// if some error in connection 
 inp = connection.getErrorStream();

查看this获取更多细节的答案。

根据文档,它返回

如果有任何错误,则返回错误流;如果没有错误,则返回 null。当连接未连接或服务器未发送有用的数据时也会返回 null。

.


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接