Android中的SocketTimeoutException超时 [英] SocketTimeoutException timeout in Android

查看:1028
本文介绍了Android中的SocketTimeoutException超时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在通过GET请求从Web上获取JSON数据.即使问题似乎是概念性的",代码也如下.

I'm fetching JSON data from the web via GET request. The code is the following, even though the problems seems to be "conceptual".

/**
 * Make an HTTP request to the given URL and return a String as the response.
 */
public static String makeHttpRequest(URL url) throws IOException {
    String jsonResponse = "";

    //Check that url is not null
    if(url == null){
        return jsonResponse;
    }

    HttpURLConnection urlConnection = null;
    InputStream inputStream = null;
    try {
        urlConnection = (HttpURLConnection) url.openConnection();
        urlConnection.setRequestMethod("GET");
      urlConnection.setReadTimeout(10000 /* milliseconds */);
           urlConnection.setConnectTimeout(15000 /* milliseconds */);
         urlConnection.connect();

        //If the request was successfull (code 200)
        //then read the imput string and parse the response
        if(urlConnection.getResponseCode() == 200) {
            inputStream = urlConnection.getInputStream();
            jsonResponse = readFromStream(inputStream);
        }
        else {
            Log.e(LOG_TAG_MAIN, "Error Response code" + urlConnection.getResponseCode());
        }

    } catch (IOException e) {
        Log.e(LOG_TAG_MAIN, "Problem the JSON results", e);
    } finally {
        if (urlConnection != null) {
            urlConnection.disconnect();
        }
        if (inputStream != null) {
            // Closing the input stream could throw an IOException, which is why
            // the makeHttpRequest(URL url) method signature specifies than an IOException
            // could be thrown.
            inputStream.close();
        }
    }
    return jsonResponse;
}
//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
/**
 * Convert the {@link InputStream} into a String which contains the
 * whole JSON response from the server.
 */
public static String readFromStream(InputStream inputStream) throws IOException {
    StringBuilder output = new StringBuilder();
    if (inputStream != null) {
        InputStreamReader inputStreamReader = new InputStreamReader(inputStream, Charset.forName("UTF-8"));
        BufferedReader reader = new BufferedReader(inputStreamReader);
        String line = reader.readLine();
        while (line != null) {
            output.append(line);
            line = reader.readLine();
        }
    }
    return output.toString();
}

实际上,以下代码工作了几个月,但突然开始抛出:

Indeed the following code worked for months, but suddenly started throwing:

E/com.example.android.abcfolio.MainActivity: Problem the JSON results
                                             java.net.SocketTimeoutException: timeout
 at com.android.okhttp.okio.Okio$3.newTimeoutException(Okio.java:207)
 at com.android.okhttp.okio.AsyncTimeout.exit(AsyncTimeout.java:250)
 at com.android.okhttp.okio.AsyncTimeout$2.read(AsyncTimeout.java:217)
 at com.android.okhttp.okio.RealBufferedSource.request(RealBufferedSource.java:71)
 at com.android.okhttp.okio.RealBufferedSource.require(RealBufferedSource.java:64)
 at com.android.okhttp.okio.RealBufferedSource.readHexadecimalUnsignedLong(RealBufferedSource.java:270)
 at com.android.okhttp.internal.http.HttpConnection$ChunkedSource.readChunkSize(HttpConnection.java:479)
 at com.android.okhttp.internal.http.HttpConnection$ChunkedSource.read(HttpConnection.java:460)
 at com.android.okhttp.okio.RealBufferedSource.read(RealBufferedSource.java:50)
 at com.android.okhttp.okio.RealBufferedSource.exhausted(RealBufferedSource.java:60)
 at com.android.okhttp.okio.InflaterSource.refill(InflaterSource.java:101)
 at com.android.okhttp.okio.InflaterSource.read(InflaterSource.java:62)
 at com.android.okhttp.okio.GzipSource.read(GzipSource.java:80)
 at com.android.okhttp.okio.RealBufferedSource$1.read(RealBufferedSource.java:349)
 at java.io.InputStreamReader.read(InputStreamReader.java:233)
 at java.io.BufferedReader.fillBuf(BufferedReader.java:145)
 at java.io.BufferedReader.readLine(BufferedReader.java:397)
 at com.example.android.abcfolio.utils.NetworkCommonUtils.readFromStream(NetworkCommonUtils.java:102)
 at com.example.android.abcfolio.utils.NetworkCommonUtils.makeHttpRequest(NetworkCommonUtils.java:68)
 at com.example.android.abcfolio.utils.NetworkCoinMarketCapUtils.fetchCoinMarketCapData(NetworkCoinMarketCapUtils.java:44)
 at com.example.android.abcfolio.sync.CoinsSyncTask.syncCoins(CoinsSyncTask.java:65)
 at com.example.android.abcfolio.sync.CoinsFirebaseJobService$1.doInBackground(CoinsFirebaseJobService.java:64)
 at com.example.android.abcfolio.sync.CoinsFirebaseJobService$1.doInBackground(CoinsFirebaseJobService.java:53)
 at android.os.AsyncTask$2.call(AsyncTask.java:295)
 at java.util.concurrent.FutureTask.run(FutureTask.java:237)
 at android.os.AsyncTask$SerialExecutor$1.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)

因为,我从没有碰过这段代码,但是我只在代码的其他部分添加了其他功能,所以我不了解发生了什么.我试图增加超时时间,但是错误实际上会立即显示出来,因此增加时间似乎毫无用处. 我排除了这是由于请求的大小所致,因为即使我只请求所有JSON的子集,它仍然会抱怨.

Since, I never touched this code, but I've only added other functionality in other parts of the code, I don't understand what's going on. I've tried to raise the timeout times, but the error actually shows up immediately, so increasing the time seems to be useless. I exclude that this is due to the size of the request, since even if I ask for only a subset of all the JSON it still complains.

问题可能出在我查询的网站上?也许他们目前有太多要求?也许我用于开发的手机中有太多请求被禁止使用?

It's possible that the problem is in the website that I'm querying? Maybe they have too many request at the moment? Of maybe my phone that I use for developing has been banned for too many requests?

编辑并附带其他信息: 1)问题是断断续续的.有时,该应用程序可以正常运行,并且所有数据均已正确加载. 2)有时此消息显示在LogCat中,我不确定是否相关(尤其是fmradio.jar):

EDIT with additional info: 1) The problems is intermittent. Sometimes the app works fine and all the data are loaded correctly. 2)Sometimes this messages shows up in the LogCat, I'm not sure if is related (the fmradio.jar in particular):

03-12 12:49:36.600 16457-16457/? W/System: ClassLoader referenced unknown path: /data/app/com.example.android.abcfolio-2/lib/arm64
03-12 12:49:36.603 16457-16457/? I/InstantRun: Instant Run Runtime started. Android package is com.example.android.abcfolio, real application class is null.

                                               [ 03-12 12:49:36.607 16457:16457 W/         ]
                                               Unable to open '/system/framework/qcom.fmradio.jar': No such file or directory
03-12 12:49:36.607 16457-16457/? W/art: Failed to open zip archive '/system/framework/qcom.fmradio.jar': I/O Error

                                        [ 03-12 12:49:36.607 16457:16457 W/         ]
                                        Unable to open '/system/framework/oem-services.jar': No such file or directory
03-12 12:49:36.607 16457-16457/? W/art: Failed to open zip archive '/system/framework/oem-services.jar': I/O Error
03-12 12:49:37.149 16457-16470/? I/art: Debugger is no longer active
03-12 12:49:39.030 16457-16457/com.example.android.abcfolio W/System: ClassLoader referenced unknown path: /data/app/com.example.android.abcfolio-2/lib/arm64
03-12 12:49:43.962 16457-16457/com.example.android.abcfolio W/art: Before Android 4.1, method android.graphics.PorterDuffColorFilter android.support.graphics.drawable.VectorDrawableCompat.updateTintFilter(android.graphics.PorterDuffColorFilter, android.content.res.ColorStateList, android.graphics.PorterDuff$Mode) would have incorrectly overridden the package-private method in android.graphics.drawable.Drawable

3)还有其他多种警告,例如

3)There other multiple warnings like

W/PathParser: Points are too far apart 4.000000000000003 

这些应归因于ConstraintLayout.是否有可能使用了过多的内存来在主线程上执行图形工作,而这会变成http请求中的错误? (对我来说似乎不太可能,但这可以解释为什么在我用ConstraintLayout插入了许多视图之后现在出现此问题的原因)

These should be due to ConstraintLayout. It is possible that it is using too much memory to perform graphic work on the main thread and this turns into errors in the http request? (it seems unlikely to me, but it could explain why this problem is showing up now, after I've inserted many views with ConstraintLayout)

4)在应用程序中,我以两种不同的方式获取数据:一种是使用扩展了AsyncTaskLoader的简单Loader,另一种是使用Firebase Job Service.是第二个产生问题的方法,即使它们获取相同的API并使用上面编写的两种方法.

EDIT 2: 4) In the app I'm fetching the data in two different ways: one with a simple Loader that extends AsyncTaskLoader, and another one with a Firebase Job Service. Is the second one that gives problems, even though they fetch the same API and use both the two methods written above.

5)我现在确定问题不是由于最近对代码所做的更改所致,因为即使该应用程序的较旧备份版本也具有相同的行为. 6)现在抛出这个:

EDIT 3: 5) I'm now sure that the problem is not due to changes made recently in the code, since even an older backup version of the app behaves in the same way. 6) Now it's throwing this:

Problem parsing the JSON results
                                             java.io.EOFException
                                                 at com.android.okhttp.okio.RealBufferedSource.require(RealBufferedSource.java:64)
                                                 at com.android.okhttp.okio.RealBufferedSource.readHexadecimalUnsignedLong(RealBufferedSource.java:270)
                                                 at com.android.okhttp.internal.http.HttpConnection$ChunkedSource.readChunkSize(HttpConnection.java:479)
                                                 at com.android.okhttp.internal.http.HttpConnection$ChunkedSource.read(HttpConnection.java:460)
                                                 at com.android.okhttp.okio.RealBufferedSource.read(RealBufferedSource.java:50)
                                                 at com.android.okhttp.okio.RealBufferedSource.exhausted(RealBufferedSource.java:60)
                                                 at com.android.okhttp.okio.InflaterSource.refill(InflaterSource.java:101)
                                                 at com.android.okhttp.okio.InflaterSource.read(InflaterSource.java:62)
                                                 at com.android.okhttp.okio.GzipSource.read(GzipSource.java:80)
                                                 at com.android.okhttp.okio.RealBufferedSource$1.read(RealBufferedSource.java:349)
                                                 at java.io.InputStreamReader.read(InputStreamReader.java:233)
                                                 at java.io.BufferedReader.fillBuf(BufferedReader.java:145)
                                                 at java.io.BufferedReader.readLine(BufferedReader.java:397)
                                                 at com.example.android.abcfolio.utils.NetworkCommonUtils.readFromStream(NetworkCommonUtils.java:106)
                                                 at com.example.android.abcfolio.utils.NetworkCommonUtils.makeHttpRequest(NetworkCommonUtils.java:72)
                                                 at com.example.android.abcfolio.utils.NetworkCoinMarketCapUtils.fetchCoinMarketCapData(NetworkCoinMarketCapUtils.java:44)
                                                 at com.example.android.abcfolio.sync.CoinsSyncTask.syncCoins(CoinsSyncTask.java:89)
                                                 at com.example.android.abcfolio.sync.CoinsSyncIntentService.onHandleIntent(CoinsSyncIntentService.java:33)
                                                 at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:66)
                                                 at android.os.Handler.dispatchMessage(Handler.java:102)
                                                 at android.os.Looper.loop(Looper.java:148)
                                                 at android.os.HandlerThread.run(HandlerThread.java:61)

6)我已经记录了urlConnection.getResponseCode()+ urlConnection.getResponseMessage(),有时,而不是成功代码200,它返回:504网关超时.

EDIT 4: 6) I've logged urlConnection.getResponseCode() + urlConnection.getResponseMessage() and sometimes, instead of the success code 200, it returns: 504Gateway Time-out.

推荐答案

经过多次试验,我确实得出结论,问题出在服务器端,因此没有真正的解决方法. 我们可以做的是优雅地处理异常.

After many trials, I've concluded indeed that the problem is server side, so there is no real way to solve it. What we can do is to handle gracefully the exception.

这篇关于Android中的SocketTimeoutException超时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆