我正在通过GET请求从Web获取JSON数据。代码如下,尽管问题似乎是“概念上的”。Android中的SocketTimeoutException超时
/**
* 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();
}
事实上,下面的代码工作了几个月,却突然开始呕吐:
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的一个子集,它仍然抱怨。
问题可能出在我查询的网站上?也许他们目前有太多的要求?我用于开发的手机可能有太多请求被禁止了吗?
EDIT与附加信息: 1)存在的问题是间歇性的。有时应用程序工作正常,所有的数据加载正确。 2)有时,这种消息显示了在logcat中,我不知道,如果是相关的(尤其是fmradio.jar):
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)有其他多个警告信息,如
W/PathParser: Points are too far apart 4.000000000000003
这些应该是由于ConstraintLayout。它可能会使用太多的内存在主线程上执行图形工作,并且这会变成http请求中的错误? (这似乎不太可能对我来说,但它可以解释为什么现在出现这个问题,因为我已经用ConstraintLayout插入了很多视图)
编辑2: 4)在应用程序中,我将数据提取到两个不同的方式:使用一个简单的Loader扩展AsyncTaskLoader,另一个使用Firebase Job Service。是第二个问题,即使他们获取相同的API并使用上面写的两个方法。
编辑3: 5)我现在确定问题不是由于最近在代码中所做的更改导致的,因为即使应用程序的较旧备份版本的行为方式相同。 6)现在它抛出这样的:
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)
编辑4: 6)我已经登录urlConnection.getResponseCode()+ urlConnection.getResponseMessage(),有时,而不是成功代码200,它返回:504Gateway时间到。
您是否尝试过增加服务器套接字超时?通常服务器套接字在1或2分钟后超时。请先使用公共休息来测试您的代码,以查看服务器或客户端是否超时。 –
我应该调用什么方法来增加服务器套接字超时?我以前尝试使用urlConnection.setReadTimeout(10000/*毫秒* /); urlConnection.setConnectTimeout(15000/*毫秒* /);通过加倍这些值 – Rexcirus
请测试您的网址与邮政人,以确保它的工作正常。 – Ibrahim