应用程序在 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 的异常。因为 SocketTimeoutExceptionIOException 的 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) {
            }
        }
    }
}