仅在 Android 而非 iOS 上使用“Volley”发出的服务器请求超时
Posted
技术标签:
【中文标题】仅在 Android 而非 iOS 上使用“Volley”发出的服务器请求超时【英文标题】:Timeout for server request made using "Volley" only on Android not iOS 【发布时间】:2016-02-07 04:23:05 【问题描述】:在我的一个应用程序中,我使用 Google 提供的 volley
向服务器发送请求。
问题:onErrorResponse(VolleyError error)
上的超时和错误对象为空
到目前为止我所尝试的:
1) 首先我得到了空错误对象,所以使用下面的代码解决了它:
@Override
protected void deliverResponse(String response)
super.deliverResponse(response);
@Override
public void deliverError(VolleyError error)
super.deliverError(error);
DebugLog.e("deliverResponse", "getNetworkTimeMs : " + error.getNetworkTimeMs());
到目前为止,当我得到错误对象 null
时,我已经知道发生了 timeout
。
2) 现在申请适用于android
和ios
和web
但timeout
仅适用于Android
。
请求的排球日志:
BasicNetwork.logSlowRequests: HTTP response for request
编辑说明:
在服务器端开发的 Web 服务对于所有三个实例(Android、Web 和 iOS)都是相同的。
Timeout
发生在过多用户向服务器发出请求时。
我已将超时设置为 2 分钟,尽管有时凌空会在 30 秒内引发超时。
我有很多关于更改服务器的答案,但因为不可能,所以请提供任何其他解决方案。
我还想补充一点,如果我能获得更多关于凌空何时可以超时的信息?
我看过的参考资料:
Optimizing Volley
httpclient-often-times-out-using-wifi-is-going-fine-with-3g
long_xmlhttprequest_ajax_requests_timeout_on_android
已编辑:
我还设置了如下重试策略:
request.setRetryPolicy(new DefaultRetryPolicy(DefaultRetryPolicy.DEFAULT_TIMEOUT_MS * 48,
0, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
如果连接超时,我也不想重试。
我怎样才能进行有效的服务调用来解决timeout
的问题。
如有任何帮助,将不胜感激。
谢谢。
【问题讨论】:
您在 volley 中使用的 api 是什么?我正在使用 OKHttpStack,它通过 volley 扩展了 HurlStack。 @Madhukar Hebbar:我使用了volley
.. 提供的简单'StringRequest'类!!
我遇到了类似的问题,我所做的是我为 DefaultRetryPolicy 的超时值添加了 0,这似乎表现为无/无限超时。
您是因为太多用户同时请求而遇到这个问题吗?从 UX/UI 的角度来看,这似乎也是一个问题。也许增加超时将解决功能问题,那么用户等待响应时间过长的问题呢?用户的注意力很短,不想长时间盯着微调器。也许通过负载均衡来提高服务器的性能,或者硬件升级会是更好的解决方案?
你试过喜欢吗:***.com/a/21762518/1318946
【参考方案1】:
由于我试图解决这个问题大约两个月,我没有得到任何完美的解决方案。虽然我分析了一些事实如下:
-
您可以升级服务器的性能
我尝试使用
HttpURLConnection
发出网络服务请求,但仍然遇到同样的问题。
所以我认为这个问题并不是 volley 所特有的,但是如果你遇到这个问题,那么我建议通过在RetryPolicy
下方进行自定义来提高服务器性能:
int x=2;// retry count
request.setRetryPolicy(new DefaultRetryPolicy(DefaultRetryPolicy.DEFAULT_TIMEOUT_MS * 48,
x, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
希望它会有所帮助。
总是欢迎提出建议:)
如果您找到更合适的解决方案,请在下方评论。
谢谢!
【讨论】:
仍然无法正常工作..我输入的代码与您在答案中提到的相同。【参考方案2】:恕我直言,您可以参考以下内容:
在BasicNetwork.java
里面,你会发现一些信息,比如:
...
private static int SLOW_REQUEST_THRESHOLD_MS = 3000;
...
/**
* Logs requests that took over SLOW_REQUEST_THRESHOLD_MS to complete.
*/
private void logSlowRequests(long requestLifetime, Request<?> request,
byte[] responseContents, StatusLine statusLine)
if (DEBUG || requestLifetime > SLOW_REQUEST_THRESHOLD_MS)
VolleyLog.d("HTTP response for request=<%s> [lifetime=%d], [size=%s], " +
"[rc=%d], [retryCount=%s]", request, requestLifetime,
responseContents != null ? responseContents.length : "null",
statusLine.getStatusCode(), request.getRetryPolicy().getCurrentRetryCount());
...
// if the request is slow, log it.
long requestLifetime = SystemClock.elapsedRealtime() - requestStart;
logSlowRequests(requestLifetime, request, responseContents, statusLine);
...
因此,如果您的项目使用 Google 的 volley 作为模块(而不是 JAR 文件),您可以更新 BasicNetwork.java
,增加 SLOW_REQUEST_THRESHOLD_MS
的值,例如可能 10000 (ms) 或更多。
另一种选择,根据@neuron 对以下问题的回答:
How to optimize network-queue-take in android Volley? (Volley Google IO 2013)
我认为您可以尝试通过在您的应用中使用以下构造函数来增加 NETWORK_THREAD_POOL_SIZE 的值:
public RequestQueue(Cache cache, Network network, int threadPoolSize)
this(cache, network, threadPoolSize,
new ExecutorDelivery(new Handler(Looper.getMainLooper())));
P/S:如果您只想在不增加 NETWORK_THREAD_POOL_SIZE 的情况下不再显示 BasicNetwork.logSlowRequests: HTTP response for request
行,只需在上面的 logSlowRequests...
行注释(//
)(当您的应用使用Google 的 volley 作为一个模块 - 不是 jar 文件,不是 build.gradle
文件中的 compile mcxiaoke...
)
希望对你有帮助!
【讨论】:
我如何在Volley.newRequestQueue();
中使用这个构造函数?
我觉得你可以试试下面的int threadPoolSize = 10; Cache cache = new DiskBasedCache(getCacheDir(), 5* 1024 * 1024); Network network = new BasicNetwork(new HurlStack()); RequestQueue queue = new RequestQueue(cache, network, threadPoolSize); queue.start();
@BNK:试过了..没有解决。又是另一个问题。当我将超时定义为2 minutes
时,凌空在甚至 1 分钟未完成之前抛出超时。比如50秒。你对此有什么想法吗?
如果你用谷歌官方的volley而不是mcxiaoke的,你可以编辑你的BasicNetwork.java,增加SLOW_REQUEST_THRESHOLD_MS
,试试10000以上。关于another issue
我不知道:)
对于您的超时问题,请尝试阅读groups.google.com/forum/#!topic/volley-users/onA_uS9KAno【参考方案3】:
public class JGet extends Request
private final Response.Listener listener;
public JGet(final String url, List params,
Response.Listener responseListener)
super(Request.Method.GET, NetUtils.getUrlWithParams(url, params), new Response.ErrorListener()
@Override
public void onErrorResponse(VolleyError volleyError)
NetUtils.dealVolleyError(volleyError, url);
);
this.listener = responseListener;
this.setRetryPolicy(new DefaultRetryPolicy(20 * 1000, 0, 1.0f));
LogUtils.e("request-start--->");
LogUtils.e(url);
LogUtils.e(params);
LogUtils.e("request-start--->");
设置超时时间。
【讨论】:
【参考方案4】:在使用 volley 向 php 文件发送请求时,尽量不要使用 require 语句连接到您的数据库。 我注意到只有当我使用类似(需要“init.php”)时才会超时 但是当我直接将我的数据库连接信息放在同一个文件中时,一切似乎都很好。
【讨论】:
【参考方案5】:request.setRetryPolicy(new DefaultRetryPolicy(50000, 5, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT))
【讨论】:
以上是关于仅在 Android 而非 iOS 上使用“Volley”发出的服务器请求超时的主要内容,如果未能解决你的问题,请参考以下文章
任务不可序列化:java.io.NotSerializableException 仅在类而非对象上调用闭包外的函数时
使用 Google 登录无法在 Android 上运行(仅在 iOS 上) - Flutter
如何仅在 IOS 上运行 Detox 测试并禁用 Android 运行
在 React 本机键盘仅在 IOS 的模态上显示,在 android 中工作正常