【问题标题】:Retry request onErrorResponse Android volley重试请求 onErrorResponse Android 凌空
【发布时间】:2014-08-31 20:09:32
【问题描述】:

当我在 的 android volley 请求中收到错误时,我想重试该请求。我怎样才能做到这一点?

【问题讨论】:

  • 出现超时错误后可以再次执行同样的请求,你试过了吗?
  • 如何从 onResponse 执行它?我应该在 onResponse 中使用 VolleyPorvider.addRequest() 吗?

标签: onerrorrepsonse request android-volley


【解决方案1】:

好吧,您可以创建RetryPolicy 来更改默认重试行为,只指定timeout millisecondsretry count 参数:

public class YourRequest extends StringRequest {
    public YourRequest(String url, Response.Listener<String> listener,
                       Response.ErrorListener errorListener) {
        super(url, listener, errorListener);
        setRetryPolicy(new DefaultRetryPolicy(DefaultRetryPolicy.DEFAULT_TIMEOUT_MS,
                DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
    }
}

另一种方法是估计VolleyError,如果是TimeoutError实例,则再次重新执行相同的请求:

public static void executeRequest() {
    RequestQueue.add(new YourRequest("http://your.url.com/", new Response.Listener<String>() {
        @Override
        public void onResponse(String response) {
        }
    }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            if (error instanceof TimeoutError) {
                // note : may cause recursive invoke if always timeout.
                executeRequest();
            }
        }
    }));
}

此时你可能有一个问题:“Volley 是否提供了一些重试回调方法?”,答案是“无”。但是有一个项目调用Netroid,它基于Volley并满足前面的问题,有了它,如果你关心它,你可以进行重试回调,你可以计算重试到来时使用了多少时间以及这个请求执行了多长时间,像这样的代码风格:

final String REQUESTS_TAG = "Request-Demo";
String url = "http://facebook.com/";
JsonObjectRequest request = new JsonObjectRequest(url, null, new Listener<JSONObject>() {
    long startTimeMs;
    int retryCount;

    @Override
    public void onPreExecute() {
        startTimeMs = SystemClock.elapsedRealtime();
    }

    @Override
    public void onFinish() {
        RequestQueue.add(request);
        NetroidLog.e(REQUESTS_TAG);
    }

    @Override
    public void onRetry() {
        long executedTime = SystemClock.elapsedRealtime() - startTimeMs;
        if (++retryCount > 5 || executedTime > 30000) {
            NetroidLog.e("retryCount : " + retryCount + " executedTime : " + executedTime);
            mQueue.cancelAll(REQUESTS_TAG);
        } else {
            NetroidLog.e(REQUESTS_TAG);
        }
    }
});

request.setRetryPolicy(new DefaultRetryPolicy(5000, 20, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
request.setTag(REQUESTS_TAG);
RequestQueue.add(request);

Netroid 还有许多其他方便且强大的功能,希望对您有所帮助:)。

【讨论】:

    【解决方案2】:

    您可以设置计数器变量以尝试特定时间,而无需使其完全递归

      static int count=10; //so its will try ten time
    public void userLogin(final View view)
    {
        final RequestQueue requestQueue= Volley.newRequestQueue(getApplicationContext());
        String url = "http://192.168.43.107/mobodb/register.php";
      StringRequest stringRequest=new StringRequest(Request.Method.POST,url,new Response.Listener<String>()
        {
            @Override
            public void onResponse(String response) {
     Toast.makeText(getApplicationContext(),"Updated",Toast.LENGTH_LONG).show();
                }
            }
        },new Response.ErrorListener()
        {
            @Override
            public void onErrorResponse(VolleyError error) {
                count=count-1;
                Toast.makeText(getApplicationContext(),"Retry left"+count,Toast.LENGTH_LONG).show();
                if (count>0) {
                    // note : may cause recursive invoke if always timeout.
                    userLogin(view);
                }
                else
                {
                    Toast.makeText(getApplicationContext(),"Request failed pls check network connection or the error is "+error.getMessage(),Toast.LENGTH_LONG).show();
                }
            }
        })
        {
            @Override
            protected Map<String, String> getParams() throws AuthFailureError {
               Map<String,String> paramter=new HashMap<String,String>();
            paramter.put("name",login_name);
                paramter.put("user_pass",login_pass);
                return paramter;
            }
        };
        requestQueue.add(stringRequest);
        stringRequest.setRetryPolicy(new DefaultRetryPolicy(20 * 1000, 10, 1.0f));
    

    您还可以检查响应,您可以在其中从 php 返回并处理您的 java 类

    @Override
            public void onResponse(String response) {
    
                if(response.contains("no record found for"))
                Toast.makeText(getApplicationContext(),response.toString(),Toast.LENGTH_LONG).show();
                else
                {
                    Toast.makeText(getApplicationContext(),"Updated num of row is"+response.toString(),Toast.LENGTH_LONG).show();
                }
    
            }
    

    您的 PHP 代码将是

    if($res){
    $resp=mysql_affected_rows();
    if($resp==0)
    {
    $resp="no record found for".$_POST['name'];
    }
    if($resp==1 or $resp>1)
    {
    $resp=mysql_affected_rows();
    }else $resp="efrror is".mysql_error();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-12-17
      • 2016-11-28
      • 2017-06-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多