volley网络编程

来源:互联网 发布:有装新风后悔的吗 知乎 编辑:程序博客网 时间:2024/06/16 22:13

一 简介

      android 开发离不开网络编程,通常情况下都是使用HTTP 协议。 谷歌虽然提供了HTTPURLConnection 来进行网络通信。 但是需要编写大量代码进行 缓存和请求调度。

     所以2013年, google 提供了一个新的网络框架Volley。

     Volley 使用简单 ,非常适用于那些网络流量不大, 但是使用频繁的场景。

二  Volley 的重点类和使用方法

      首先介绍一下Volley 框架下得重点类和重点方法。

      1.  Volley

   Volley 是Volley 框架的起始类,它只有两个静态方法, 作用是获得请求队列。

     public static RequestQueue newRequestQueue(Context context) 
     public static RequestQueue newRequestQueue(Context context, HttpStack stack)

   2. RequestQueue

       RequestQueue  维护应用所有的网络请求, 只要我们将我们的网络请求放到队列中, 它会自动处理。
       public Request add(Request request) 

3. Request

       Volley 框架定义了不同的request 类型来处理了不同类型的网络请求。 但是Request 是所有网络请求的基类。
      
* @param <T> The type of parsed response this request expects. */public abstract class Request<T> implements Comparable<Request<T>> {    /**     * Supported request methods.     */    public interface Method {        int DEPRECATED_GET_OR_POST = -1;        int GET = 0;        int POST = 1;        int PUT = 2;        int DELETE = 3;    }......    /**     * Creates a new request with the given URL and error listener.  Note that     * the normal response listener is not provided here as delivery of responses     * is provided by subclasses, who have a better idea of how to deliver an     * already-parsed response.     *     * @deprecated Use {@link #Request(int, String, com.android.volley.Response.ErrorListener)}.     */    public Request(String url, Response.ErrorListener listener) {        this(Method.DEPRECATED_GET_OR_POST, url, listener);    }    /**     * Creates a new request with the given method (one of the values from {@link Method}),     * URL, and error listener.  Note that the normal response listener is not provided here as     * delivery of responses is provided by subclasses, who have a better idea of how to deliver     * an already-parsed response.     */    public Request(int method, String url, Response.ErrorListener listener) {        mMethod = method;        mUrl = url;        mErrorListener = listener;        setRetryPolicy(new DefaultRetryPolicy());        mDefaultTrafficStatsTag = TextUtils.isEmpty(url) ? 0: Uri.parse(url).getHost().hashCode();    }

对以上源码进行说明,T 是网络请求希望的返回类型。 它有两个构造函数,method 是请求方式在Interface Method 中定义, url 是请求的URL,listen 是当网络返回错误时的处理接口。
      1) StringRequest
      网络返回字符串时, 可以使用此类型的请求。
     
public class StringRequest extends Request<String> {    private final Listener<String> mListener;    /**     * Creates a new request with the given method.     *     * @param method the request {@link Method} to use     * @param url URL to fetch the string at     * @param listener Listener to receive the String response     * @param errorListener Error listener, or null to ignore errors     */    public StringRequest(int method, String url, Listener<String> listener,            ErrorListener errorListener) {        super(method, url, errorListener);        mListener = listener;    }    /**     * Creates a new GET request.     *     * @param url URL to fetch the string at     * @param listener Listener to receive the String response     * @param errorListener Error listener, or null to ignore errors     */    public StringRequest(String url, Listener<String> listener, ErrorListener errorListener) {        this(Method.GET, url, listener, errorListener);    }}

与父类相比,StringRequest 的构造函数, 多了一个参数Listener<String> listener,这个listen 是当网络返回想要的结果的处理接口。
      2) JsonRequest JsonObjectRequest和JsonArrayRequest
      由于JSON 有两种JSONObject,JSONArray. 所以Volley框架也分别定义了JsonObjectRequest和JsonArrayRequest, 它们有共同的父类JsonRequest。
      
      JsonRequest:
public abstract class JsonRequest<T> extends Request<T> {    /**     * Deprecated constructor for a JsonRequest which defaults to GET unless {@link #getPostBody()}     * or {@link #getPostParams()} is overridden (which defaults to POST).     *     * @deprecated Use {@link #JsonRequest(int, String, String, Listener, ErrorListener)}.     */    public JsonRequest(String url, String requestBody, Listener<T> listener,            ErrorListener errorListener) {        this(Method.DEPRECATED_GET_OR_POST, url, requestBody, listener, errorListener);    }    public JsonRequest(int method, String url, String requestBody, Listener<T> listener,            ErrorListener errorListener) {        super(method, url, errorListener);        mListener = listener;        mRequestBody = requestBody;    }}


      
      JsonObjectRequest:
public class JsonObjectRequest extends JsonRequest<JSONObject> {    public JsonObjectRequest(int method, String url, JSONObject jsonRequest,            Listener<JSONObject> listener, ErrorListener errorListener) {        super(method, url, (jsonRequest == null) ? null : jsonRequest.toString(), listener,                    errorListener);    }    public JsonObjectRequest(String url, JSONObject jsonRequest, Listener<JSONObject> listener,            ErrorListener errorListener) {        this(jsonRequest == null ? Method.GET : Method.POST, url, jsonRequest,                listener, errorListener);    }}

JsonArrayRequest:
public class JsonArrayRequest extends JsonRequest<JSONArray> {    /**     * Creates a new request.     * @param url URL to fetch the JSON from     * @param listener Listener to receive the JSON response     * @param errorListener Error listener, or null to ignore errors.     */    public JsonArrayRequest(String url, Listener<JSONArray> listener, ErrorListener errorListener) {        super(Method.GET, url, null, listener, errorListener);    }}


它们与StringRequest 与相似的构造函数,listener 是成功处理的回调的接口。 不过JsonRequest 多了一个参数requestBody参数。
   3)ImageRequest
     ImageRequest 是加载网络图片用到的Request.
public class ImageRequest extends Request<Bitmap> {    public ImageRequest(String url, Response.Listener<Bitmap> listener, int maxWidth, int maxHeight,            Config decodeConfig, Response.ErrorListener errorListener) {        super(Method.GET, url, errorListener);        setRetryPolicy(                new DefaultRetryPolicy(IMAGE_TIMEOUT_MS, IMAGE_MAX_RETRIES, IMAGE_BACKOFF_MULT));        mListener = listener;        mDecodeConfig = decodeConfig;        mMaxWidth = maxWidth;        mMaxHeight = maxHeight;    }}

maxWidth 是最大宽度,maxHeight是最大高度, 设置为0 时,表示原始图片大小, 不压缩。
decodeConfig 由Bitmap.Config 定义。
Listen 同样是回调的处理。

4 Response

     由以上介绍可以看到, 一个重要的点就是实现回调处理的Response.Listener.

public class Response<T> {    /** Callback interface for delivering parsed responses. */    public interface Listener<T> {        /** Called when a response is received. */        public void onResponse(T response);    }    /** Callback interface for delivering error responses. */    public interface ErrorListener {  this.error = error;    }}

实现回调的Listener, 必须实现onResponse() 方法。

5 Volley的使用方法

   总结以下Volley 的使用方法:
   1)Volley.newRequestQueue()方法获得RequestQueue
   2) 实现处理回调Listen
   3) 建立 合适的Request
   4) RequestQueue.add(Request)
   5)在Listen 中处理回调结果
三 实例
public class MainActivity extends AppCompatActivity {    private Button btn;    private TextView view;    private ImageView imageView;    private RequestQueue queue;    private StringRequest request;    private JsonObjectRequest jsonObjectRequest;    private  ImageRequest Imagerequest;    private final int TEXT_HANDLE=0x123;    private final int JSON_HANDLE=0x124;    private final int IMAGE_HNADLE=0x125;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.main);        btn=(Button)findViewById(R.id.btn);        view=(TextView)findViewById(R.id.text);        imageView=(ImageView)findViewById(R.id.image);        queue= Volley.newRequestQueue(this);        btn.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                /* request=new StringRequest(Request.Method.GET,"http://m.weather.com.cn/data/101010100.html",                      new handleLister(),new errorLister());*/                /*jsonObjectRequest=new JsonObjectRequest(Request.Method.GET,"http://m.weather.com.cn/mtown/index?lat=30.274085&lon=120.15507",                        null,new JsonhandleLister(),new errorLister());*/                Imagerequest=new ImageRequest("http://p1.meituan.net/deal/a5c0180d48419fe09f8edb0f267a7e7767069.jpg",                        new ImageListener(),0,0, Bitmap.Config.RGB_565,new errorLister());                queue.add(Imagerequest);            }        });    }    Handler handle=new Handler(){        @Override        public void handleMessage(Message msg) {            super.handleMessage(msg);             switch(msg.arg1){                 case TEXT_HANDLE:{                     String text;                     text=(String)msg.obj;                     view.setText(text);                     break;                 }                 case JSON_HANDLE:{                     String text;                     text=msg.obj.toString();                     view.setText(text);                     break;                 }                 case IMAGE_HNADLE:{                     Bitmap bitmap=(Bitmap)msg.obj;                     imageView.setImageBitmap(bitmap);                 }                 default:                     break;             }        }    };    class handleLister implements Response.Listener<String>{        public void onResponse(String  s){            Message msg=new Message();            msg.arg1=TEXT_HANDLE;            msg.obj=s;            handle.sendMessage(msg);        }    }    class JsonhandleLister implements Response.Listener<JSONObject>{        public void onResponse(JSONObject  s){            Message msg=new Message();            msg.arg1=JSON_HANDLE;            msg.obj=s;            handle.sendMessage(msg);        }    }    class ImageListener implements Response.Listener<Bitmap>{        public void onResponse(Bitmap bitmap){            Message msg=new Message();            msg.arg1=IMAGE_HNADLE;            msg.obj=bitmap;            handle.sendMessage(msg);        }    }    class errorLister implements  Response.ErrorListener{        public void onErrorResponse(VolleyError error){        }    }}