仅在 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) 现在申请适用于androidioswebtimeout 仅适用于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 中工作正常

如何修复仅在 ios 而不是 android 上发生的虚线边框错误?

如何在 iOS 和 Android 的给定时间检测用户是不是仅在一台设备上处于活动状态