Android 如何处理异步任务中的连接超时

Android 如何处理异步任务中的连接超时,android,connection-timeout,Android,Connection Timeout,我有个问题还没有解决,我需要帮助 当互联网运行缓慢时,应用程序崩溃。如何检查asyntask中的连接超时 我制作了一个有时连接到web服务以获取数据的应用程序,我使用异步任务来实现这一点 当用户可以选择是重试还是取消时,我想在连接超时时创建一个警报对话框,如果用户选择重试,它将再次尝试连接 public class login extends AsyncTask<Void,Void,Void> { InputStream ins; String status, r

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

当互联网运行缓慢时,应用程序崩溃。如何检查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();


    }



   }
公共类登录扩展异步任务{
输入流;
字符串状态,结果,s=null,data=”“,js;
int-ss;
国际响应码;
@凌驾
受保护的void onPreExecute(){
super.onPreExecute();
pdlg.setTitle(“检查”);
pdlg.setMessage(“请稍候”);
pdlg.setCancelable(假);
pdlg.show();
}
@凌驾
受保护的Void doInBackground(Void…参数){
StringBuilder sb=新的StringBuilder();
ArrayList al;
试一试{
URL=新URL(“http://....login.php");
String param=“username=“+uname+”&password=“+pass;
HttpURLConnection connection=(HttpURLConnection)url.openConnection();
connection.setRequestMethod(“POST”);
连接。设置连接超时(15000);
连接。setReadTimeout(15000);
connection.setDoInput(true);
connection.setDoOutput(真);
OutputStream os=connection.getOutputStream();
BufferedWriter bw=新的BufferedWriter(新的OutputStreamWriter(os,“UTF-8”));
写入(参数);
bw.flush();
bw.close();
responseCode=connection.getResponseCode();
if(responseCode==HttpURLConnection.HTTP\u确定){
BufferedReader br=新的BufferedReader(新的InputStreamReader(connection.getInputStream());
字符串行=”;
而((line=br.readLine())!=null){
sb.追加(第+行“\n”);
}
}
data=sb.toString();
JSONObject json=新的JSONObject(数据);
status=json.getString(“status”);//{“登录状态”:“成功”,“收据详细信息”:“无可用数据”}
//js=json.getString(“登录”);//{“登录”:“失败”}
}捕获(格式错误){
i(“MalformedURLException”,e.getMessage());
}捕获(IOE异常){
Log.i(“IOException”,即getMessage());
}捕获(JSONException e){
i(“JSONException”,e.getMessage());
}
返回null;
}
受保护的void onPostExecute(void结果){
super.onPostExecute(结果);
字符串status1=status.trim();
如果(状态1.equals(“成功”)){
Toast.makeText(getApplicationContext(),“登录成功!!”,Toast.LENGTH\u SHORT.show();
意图i=新意图(Login.this,Home.class);
星触觉(i);
完成();
SharedReferences SharedReferences=PreferenceManager.GetDefaultSharedReferences(getApplicationContext());
SharedReferences.Editor=SharedReferences.edit();
编辑:putBoolean(“第一次”,假);
putString(“userrname”,uname);
编辑器.putString(“密码”,pass);
editor.apply();
Toast.makeText(getApplicationContext(),“welcome:+uname,Toast.LENGTH\u LONG.show();
}
否则{
Toast t=Toast.makeText(Login.this,“用户名或密码不正确”,Toast.LENGTH\u LONG);
t、 设置重力(底部重力,0,0);
t、 show();
}
pdlg.discouse();
}
}

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

对于连接超时,请在catch块中添加
SocketTimeoutException
,并使其崩溃,因为在没有空检查的情况下,您正在尝试在
onPostExecute

if (status.equals("timeout")) {
    // Show Alert Dialog.
}
您应该这样做,并在使用状态之前检查

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

您试图做的是以前在一些伟大的网络库中完成的。因此,我建议您使用widley使用的网络库之一。 截击

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


希望这有帮助。

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

您可以使用
getErrorStream()

HttpURLConnection connection = (HttpURLConnection) url.openConnection();
InputStream inp;

// if some error in connection 
 inp = connection.getErrorStream();
查看答案以了解更多详细信息

根据它返回的

错误流(如果有),如果没有错误,则为null 连接未连接或 服务器未发送任何有用数据