应用程序在 Android 中因 SocketTimeoutException 而崩溃
App crashes on SocketTimeoutException in Android
我已经在 Activity
中正确实施了 AsyncTask
(基于许多来源)。
我还调查了 SocketTimeoutException
并捕获了异常,您可以在下面的代码中看到。
无论如何,当我停止 webapi
并模拟 SocketTimeoutException
时,应用程序立即崩溃。 (请检查错误消息。)
调试代码转到 IOException
,然后我看到错误消息并重新启动应用程序。
代码
private class FetchHauls extends AsyncTask<String, Void, String> {
@Override
protected String doInBackground(String... params) {
HttpURLConnection urlConnection = null;
BufferedReader reader = null;
try {
AppSettings.ComplexPreferences complexPreferences = AppSettings.ComplexPreferences.getComplexPreferences(context, "App_Settings", 0);
AppSettings appSettings = complexPreferences.getObject("App_Settings", AppSettings.class);
if (appSettings != null) {
String uri = appSettings.getIpAddress() + "/api/Version1/GetGrandTotalStats";
GrandTotalStatsRequest grandTotalStatsRequest = new GrandTotalStatsRequest();
Date d = new Date();
CharSequence timeOfRequest = DateFormat.format("yyyy-MM-dd HH:mm:ss", d.getTime());
grandTotalStatsRequest.AtTime = timeOfRequest.toString();
grandTotalStatsRequest.DeviceID = appSettings.getDeviceID();
grandTotalStatsRequest.DeviceSerialNumber = appSettings.getSerialNumber();
Gson gson = new Gson();
String json = gson.toJson(grandTotalStatsRequest);
//Connect
urlConnection = (HttpURLConnection) ((new URL(uri).openConnection()));
urlConnection.setDoOutput(true);
urlConnection.setRequestProperty("Content-Type", "application/json");
urlConnection.setRequestProperty("Accept", "application/json");
urlConnection.setRequestMethod("POST");
urlConnection.setConnectTimeout(60000);
urlConnection.setReadTimeout(55000);
urlConnection.connect();
//Write
OutputStream outputStream = urlConnection.getOutputStream();
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outputStream, "UTF-8"));
writer.write(json);
writer.close();
outputStream.close();
String result = null;
//Read
InputStream inputStream = urlConnection.getInputStream();
if (inputStream != null) {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
String l = null;
StringBuilder sb = new StringBuilder();
while ((l = bufferedReader.readLine()) != null) {
sb.append(l);
}
bufferedReader.close();
result = sb.toString();
}
return result;
}
} catch (IOException e) {
} catch (Exception e) {
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
if (reader != null) {
try {
reader.close();
} catch (final IOException ex) {
}
}
}
return null;
}
@Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
if (isCancelled()) {
return;
}
swiperefresh.setRefreshing(false);
taskFetchHauls = null;
if (TextUtils.isEmpty(s)) return;
try {
// Some code...
} catch (Exception ex) {
Log.e(PAGE_TITLE, ex.getMessage());
}
}
}
}
错误
java.net.SocketTimeoutException: failed to connect to /172.15.15.2 (port 1067) after 60000ms
at libcore.io.IoBridge.connectErrno(IoBridge.java:169)
at libcore.io.IoBridge.connect(IoBridge.java:122)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:183)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:452)
at java.net.Socket.connect(Socket.java:884)
at com.android.okhttp.internal.Platform.connectSocket(Platform.java:117)
at com.android.okhttp.internal.http.SocketConnector.connectRawSocket(SocketConnector.java:160)
at com.android.okhttp.internal.http.SocketConnector.connectCleartext(SocketConnector.java:67)
at com.android.okhttp.Connection.connect(Connection.java:152)
at com.android.okhttp.Connection.connectAndSetOwner(Connection.java:185)
at com.android.okhttp.OkHttpClient.connectAndSetOwner(OkHttpClient.java:128)
at com.android.okhttp.internal.http.HttpEngine.nextConnection(HttpEngine.java:341)
at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:330)
at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:248)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:433)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:114)
at android.apps.ktk.company.gpsmegatracker.Activities.GrandStatActivity$FetchHauls.doInBackground(GrandStatActivity.java:291)
at android.apps.ktk.company.gpsmegatracker.Activities.GrandStatActivity$FetchHauls.doInBackground(GrandStatActivity.java:259)
at android.os.AsyncTask.call(AsyncTask.java:295)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor.run(AsyncTask.java:234)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
at java.lang.Thread.run(Thread.java:818)
Disconnected from the target VM, address: 'localhost:8617', transport: 'socket'
如果你想捕捉一个SocketTimeoutException
,那么你应该使用下面的模式。请仔细注意,我们捕获了从大多数 specific 到大多数 general 的异常。因为 SocketTimeoutException
是 IOException
的 child,我们先抓住前者。使用相反的顺序将导致您看到的错误。最后,我们最后抓到将军Exception
。
@Override
protected String doInBackground(String... params) {
HttpURLConnection urlConnection = null;
BufferedReader reader = null;
try {
// make the async call
}
catch (SocketTimeoutException se) {
// display timeout alert to user
}
catch (IOException e) {
// handle general IO error
}
catch (Exception e) {
// just in case you missed anything else
}
finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
if (reader != null) {
try {
reader.close();
} catch (final IOException ex) {
}
}
}
}
我已经在 Activity
中正确实施了 AsyncTask
(基于许多来源)。
我还调查了 SocketTimeoutException
并捕获了异常,您可以在下面的代码中看到。
无论如何,当我停止 webapi
并模拟 SocketTimeoutException
时,应用程序立即崩溃。 (请检查错误消息。)
调试代码转到 IOException
,然后我看到错误消息并重新启动应用程序。
代码
private class FetchHauls extends AsyncTask<String, Void, String> {
@Override
protected String doInBackground(String... params) {
HttpURLConnection urlConnection = null;
BufferedReader reader = null;
try {
AppSettings.ComplexPreferences complexPreferences = AppSettings.ComplexPreferences.getComplexPreferences(context, "App_Settings", 0);
AppSettings appSettings = complexPreferences.getObject("App_Settings", AppSettings.class);
if (appSettings != null) {
String uri = appSettings.getIpAddress() + "/api/Version1/GetGrandTotalStats";
GrandTotalStatsRequest grandTotalStatsRequest = new GrandTotalStatsRequest();
Date d = new Date();
CharSequence timeOfRequest = DateFormat.format("yyyy-MM-dd HH:mm:ss", d.getTime());
grandTotalStatsRequest.AtTime = timeOfRequest.toString();
grandTotalStatsRequest.DeviceID = appSettings.getDeviceID();
grandTotalStatsRequest.DeviceSerialNumber = appSettings.getSerialNumber();
Gson gson = new Gson();
String json = gson.toJson(grandTotalStatsRequest);
//Connect
urlConnection = (HttpURLConnection) ((new URL(uri).openConnection()));
urlConnection.setDoOutput(true);
urlConnection.setRequestProperty("Content-Type", "application/json");
urlConnection.setRequestProperty("Accept", "application/json");
urlConnection.setRequestMethod("POST");
urlConnection.setConnectTimeout(60000);
urlConnection.setReadTimeout(55000);
urlConnection.connect();
//Write
OutputStream outputStream = urlConnection.getOutputStream();
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outputStream, "UTF-8"));
writer.write(json);
writer.close();
outputStream.close();
String result = null;
//Read
InputStream inputStream = urlConnection.getInputStream();
if (inputStream != null) {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
String l = null;
StringBuilder sb = new StringBuilder();
while ((l = bufferedReader.readLine()) != null) {
sb.append(l);
}
bufferedReader.close();
result = sb.toString();
}
return result;
}
} catch (IOException e) {
} catch (Exception e) {
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
if (reader != null) {
try {
reader.close();
} catch (final IOException ex) {
}
}
}
return null;
}
@Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
if (isCancelled()) {
return;
}
swiperefresh.setRefreshing(false);
taskFetchHauls = null;
if (TextUtils.isEmpty(s)) return;
try {
// Some code...
} catch (Exception ex) {
Log.e(PAGE_TITLE, ex.getMessage());
}
}
}
}
错误
java.net.SocketTimeoutException: failed to connect to /172.15.15.2 (port 1067) after 60000ms
at libcore.io.IoBridge.connectErrno(IoBridge.java:169)
at libcore.io.IoBridge.connect(IoBridge.java:122)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:183)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:452)
at java.net.Socket.connect(Socket.java:884)
at com.android.okhttp.internal.Platform.connectSocket(Platform.java:117)
at com.android.okhttp.internal.http.SocketConnector.connectRawSocket(SocketConnector.java:160)
at com.android.okhttp.internal.http.SocketConnector.connectCleartext(SocketConnector.java:67)
at com.android.okhttp.Connection.connect(Connection.java:152)
at com.android.okhttp.Connection.connectAndSetOwner(Connection.java:185)
at com.android.okhttp.OkHttpClient.connectAndSetOwner(OkHttpClient.java:128)
at com.android.okhttp.internal.http.HttpEngine.nextConnection(HttpEngine.java:341)
at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:330)
at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:248)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:433)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:114)
at android.apps.ktk.company.gpsmegatracker.Activities.GrandStatActivity$FetchHauls.doInBackground(GrandStatActivity.java:291)
at android.apps.ktk.company.gpsmegatracker.Activities.GrandStatActivity$FetchHauls.doInBackground(GrandStatActivity.java:259)
at android.os.AsyncTask.call(AsyncTask.java:295)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor.run(AsyncTask.java:234)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
at java.lang.Thread.run(Thread.java:818)
Disconnected from the target VM, address: 'localhost:8617', transport: 'socket'
如果你想捕捉一个SocketTimeoutException
,那么你应该使用下面的模式。请仔细注意,我们捕获了从大多数 specific 到大多数 general 的异常。因为 SocketTimeoutException
是 IOException
的 child,我们先抓住前者。使用相反的顺序将导致您看到的错误。最后,我们最后抓到将军Exception
。
@Override
protected String doInBackground(String... params) {
HttpURLConnection urlConnection = null;
BufferedReader reader = null;
try {
// make the async call
}
catch (SocketTimeoutException se) {
// display timeout alert to user
}
catch (IOException e) {
// handle general IO error
}
catch (Exception e) {
// just in case you missed anything else
}
finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
if (reader != null) {
try {
reader.close();
} catch (final IOException ex) {
}
}
}
}