如何处理异步任务中的连接超时
How to Handle connection timeout in async task
我有一个问题还没有解决,我需要帮助。
当网速慢时应用程序崩溃。如何在 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();
}
}
使用这两个 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
并且它会崩溃,因为没有空检查,您正在尝试 trim onPostExecute
中的字符串
你应该这样做,并在使用状态之前检查
if(TextUtil.isEmpty(status)) {
pdlg.dismiss();
// We are getting empty response
return;
}
String status1=status.trim();
您尝试做的事情以前是在一些很棒的网络库中完成的。所以我强烈建议您使用 widley 使用的网络库之一。
齐射.
或者如果你想了解你可以只检查响应状态(或者状态代码应该是 408。我猜是连接超时)如果它 return "connection time out" 那么你可以调用您的代码再次发送到 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();
查看this答案了解更多详情..
根据doc吧returns
an error stream if any, null if there have been no errors, the
connection is not connected or the
server sent no useful data
.
我有一个问题还没有解决,我需要帮助。
当网速慢时应用程序崩溃。如何在 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();
}
}
使用这两个 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
并且它会崩溃,因为没有空检查,您正在尝试 trim onPostExecute
你应该这样做,并在使用状态之前检查
if(TextUtil.isEmpty(status)) {
pdlg.dismiss();
// We are getting empty response
return;
}
String status1=status.trim();
您尝试做的事情以前是在一些很棒的网络库中完成的。所以我强烈建议您使用 widley 使用的网络库之一。 齐射.
或者如果你想了解你可以只检查响应状态(或者状态代码应该是 408。我猜是连接超时)如果它 return "connection time out" 那么你可以调用您的代码再次发送到 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();
查看this答案了解更多详情..
根据doc吧returns
an error stream if any, null if there have been no errors, the connection is not connected or the server sent no useful data
.