【问题标题】:Volley request not taking parametersVolley 请求不带参数
【发布时间】:2015-04-21 02:06:45
【问题描述】:

我有一个自定义 volley 请求,但在发送请求时它没有接受我的参数,我的代码有什么问题? 我在getParamsgetPostParams设置了一个断点,但是没有一个通过。

我使用了com.mcxiaoke.volley:library:1.0.+,它是从 google volley 中派生出来的,以支持 maven。

我发现该课程在真实设备上运行良好,但无法在 genymotion 上运行。

public class GsonRequest<T> extends Request<T> {
  private Class<T> clazz;
  private Map<String, String> headers;
  private Map<String, String> params;
  private Listener<T> listener;

  public GsonRequest(Api api, Class<T> clazz, Listener<T> listener, ErrorListener errorListener) {
    this(api, clazz, null, null, listener, errorListener);
  }

  public GsonRequest(Api api, Class<T> clazz, Map<String, String> params, Listener<T> listener,
      ErrorListener errorListener) {
    this(api, clazz, params, null, listener, errorListener);
  }

  /**
   * Make a GET request and return a parsed object from JSON.
   *
   * @param url
   *            URL of the request to make
   * @param clazz
   *            Relevant class object, for Gson's reflection
   * @param headers
   *            Map of request headers
   */
  public GsonRequest(Api api, Class<T> clazz, Map<String, String> params, Map<String, String> headers,
      Listener<T> listener, ErrorListener errorListener) {
    super(api.method, api.url, errorListener);
    this.clazz = clazz;
    this.params = params;
    this.headers = headers;
    this.listener = listener;
  }

  // use new GsonRequest()
  @Deprecated
  public GsonRequest(String url, Class<T> clazz, Map<String, String> headers, Listener<T> listener,
      ErrorListener errorListener) {
    super(Method.GET, url, errorListener);
    this.clazz = clazz;
    this.headers = headers;
    this.listener = listener;
  }

  @Override
  public Map<String, String> getHeaders() throws AuthFailureError {
    return headers != null ? headers : super.getHeaders();
  }

  @Override
    public Map<String, String> getParams() throws AuthFailureError {  
    Map<String, String> result = params;
    return result;
    }

  @Override
  public Map<String, String> getPostParams() throws AuthFailureError {   
    Map<String, String> result = params;
    return result;
  }

  @Override
  protected void deliverResponse(T response) {
    listener.onResponse(response);
  }

  @Override
  protected Response<T> parseNetworkResponse(NetworkResponse response) {
    try {
      String json = new String(response.data, HttpHeaderParser.parseCharset(response.headers, "utf-8"));
//      Log.d("zhch", json);
      return Response.success(GsonUtils.fromJson(json, clazz), HttpHeaderParser.parseCacheHeaders(response));
    } catch (UnsupportedEncodingException e) {
      return Response.error(new ParseError(e));
    } catch (JsonSyntaxException e) {
      return Response.error(new ParseError(e));
    }
  }
}

【问题讨论】:

    标签: android android-volley


    【解决方案1】:

    此答案假定您正在尝试发出 GET 请求。

    我遇到了类似的问题。在使用 Volley 时,在传递参数方面,GET 请求与 POST 请求略有不同。 当您发出 GET 请求时,传递参数的一种方法是在 url 字符串本身内,这对我有用:

    (这是一个部分示例,但应该为您提供修改自己的代码所需的大部分内容)

    在发送请求的类中,我使用了一个小方法将参数附加到 url:

    //this method sits somewhere in your class
    private String createGetWithParams(String url, Map<String, Object> params)
    {
        StringBuilder builder = new StringBuilder();
        for (String key : params.keySet())
        {
            Object value = params.get(key);
            if (value != null)
            {
                try
                {
                    value = URLEncoder.encode(String.valueOf(value), HTTP.UTF_8);
                    if (builder.length() > 0)
                        builder.append("&");
                    builder.append(key).append("=").append(value);
                }
                catch (UnsupportedEncodingException e)
                {
                }
            }
        }
    
        return (url += "?" + builder.toString());
    }
    
    
    //this method sits somewhere in the same class, this fires the request
    public void doSomeRequest()
    {
        Map<String, Object> jsonParams = new HashMap<>();
        jsonParams.put("SomeParam", SomeParamValue);
        jsonParams.put("SomeOtherParam", SomeOtherParamValue);
    
        String url = createGetWithParams("some/request/url", jsonParams);
    
        StringRequest request = new StringRequest(Request.Method.GET, url,
                new Response.Listener<String>()
                {
                    @Override
                    public void onResponse(String response)
                    {
                     // do whatever
                    }
                },
                new Response.ErrorListener()
                {
                    @Override
                    public void onErrorResponse(VolleyError error)
                    {
                        if (null != error.networkResponse)
                        {
                            Log.d(" Volley Error Response code: ", ""+ error.networkResponse.statusCode);
                        }
                    }
                });
    
          requestQueue.add(request);
    

    我还创建了一个自定义请求类来替换 StringRequest,但这是为了更好地控制解析响应 - 不过可能会对您有所帮助,在这个类中我只覆盖响应:

    public class CustomStringRequest extends StringRequest
    {
     private final Response.Listener<String> mListener;
    
     public CustomStringRequest(int method, String url, Response.Listener<String> listener, Response.ErrorListener errorListener)
     {
        super(method,url, listener, errorListener);
        mListener = listener;
     }
    
     @Override
     protected Response<String> parseNetworkResponse(NetworkResponse response)
     {
         try
         {
             // response.data is the byte array, do whatever..
             String responseBody = new String(response.data, "utf-8");
             Log.d(" NetworkResponse", responseBody);
    
             return (Response.success(responseBody, getCacheEntry()));
         }
         catch (UnsupportedEncodingException e)
         {
             VolleyLog.e("UnsupportedEncodingException");
             Log.d("NetworkResponse Exception", e.getMessage() );
             return (null);
         }
     }
    
     @Override
     protected void deliverResponse(String response)
     {
         mListener.onResponse(response);
     }
    

    }

    我知道的另一种方式是使用特定的 http 客户端,我没有使用过这种方式,但您可能会使用 OkHttp 或类似的东西。

    希望这会有所帮助!

    【讨论】:

    • 谢谢。但我提出了一个 POST 请求。问题是该请求在真实设备上运行良好,但在 genymotion 上无法运行
    • 你能详细说明一下吗?给一些日志打印?您是否收到任何 ErrorResponse 或者请求甚至没有将模拟器留在网络中?
    • 抱歉,我无法获得更多信息。没有错误日志和错误响应,只是缺少参数的错误逻辑响应(请求由服务器发送和处理)。安装在真实设备上的相同代码可以工作。
    • 你能解决这个问题吗?我遇到了一个类似的问题,导致我无法使用 Genymotion:
    • 据我所知,volley 和 Genymotion 似乎存在一个已知问题,我通常在现场设备上进行测试,所以它从未发生在我身上,但我听说它发生了
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-02-06
    • 2014-11-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多