1、如何发送请求;
<1>.volley的三大组件: 应用创建Request并add到RequestQueue,RequestQueue处理并响应给Volley,Volley处理告知应用。 –RequestQueue 【管道 】:管理网络操作、缓存响应、解析响应的处理线程; –Request 【请求】:解析原始响应; –Volley【调度】:将已解析的响应调度回主线程。 附一个流程图解:
<2>.Volley的核心作用: Volley将已解析的响应调度回主线程,这样才能随意修改界面控件。
<3>.简易用法: 先加联网权限:android.permission.INTERNET 权限 再构建一个Request,并用add()将其添加到 RequestQueue; 最后Request会经过RequestQueue得到处理,然后其原始响应会被解析并给到Volley。
<4>.volley的设计逻辑: 调用add()时,Volley会运行一个“缓存处理线程”和一个“网络调度线程池”。 将请求添加到队列后,缓存线程会获取该请求并对其进行分类: 如果该请求可以通过缓存处理,系统会在缓存线程上解析缓存的响应,并在主线程上传送解析后的响应; 如果该请求无法通过缓存处理,则系统会将其放置到网络队列中。 【一句话:RequestQueue判断这个请求的结果在cache中是否存在,有就送给“缓存处理线程”处理,没有送给“网络调度线程池”处理】 网络调度线程池会从队列中获取该请求,执行 HTTP 事务,在线程上解析响应,将响应写入缓存,然后将解析后的响应发送给Volley。
2、如何取消请求;
<1>.取消请求:在Request对象上调用cancel() 取消请求后,Volley可以确保您的响应处理程序永远不会被调用.【注意是“响应处理程序”不调用】 因为不调用处理回调,意味着可以在Activity的onStop()方法中取消所有待处理的请求,不必担心回调时发现Activity不存在导致NPE。
通常可以跟踪所有传输中的请求,能够在适当的时间取消它们。 将一个标记对象与每个请求相关联,这样取消就知道取消哪一类了。 例如:您可以使用代表其发出请求的 Activity 标记所有相应请求,然后从 onStop() 调用 requestQueue.cancelAll(this)。 代码: add请求的地方:
public static final String TAG = "MyTag";
StringRequest stringRequest;
RequestQueue requestQueue;
stringRequest.setTag(TAG);
requestQueue.add(stringRequest);
Activity 的 onStop() 中:
@Override
protected void onStop () {
super.onStop();
if (requestQueue != null) {
requestQueue.cancelAll(TAG);
}
}
3、如何操作请求队列;
<1>.RequestQueue做两件事:一个是网络请求的传输,一个是缓存处理 Volley中有这些可用的标准实现: DiskBasedCache :提供对应的缓存和内存索引; BasicNetwork (默认):提供基于首选的 HTTP 客户端的网络传输。
BasicNetwork使用HttpURLConnection进行初始化。 代码:
RequestQueue requestQueue;
Cache cache = new DiskBasedCache(getCacheDir(), 1024 * 1024);
Network network = new BasicNetwork(new HurlStack());
requestQueue = new RequestQueue(cache, network);
requestQueue.start();
String url ="http://www.mythsun.com";
StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
}
});
requestQueue.add(stringRequest);
如果只需要发出一次性请求并且不想留下线程池,可以Volley.newRequestQueue()在需要时创建,并在响应或错误返回后调用RequestQueue的stop()。 更常见的用法是创建RequestQueue一个单例,以使其在应用程序的整个生命周期内保持运行
<2>.使用单例模式 如果应用程序频繁使用网络,那么设置一个RequestQueue可以在应用程序的整个生命周期内持续使用的实例是最有效的。 注意:RequestQueue必须使用Application上下文而不是Activity上下文来实例化。 确保在应用程序的整个生命周期内RequestQueue都是一个,而不是在每次重新创建 Activity 时(例如,当用户旋转设备时)重新创建。 代码:
public class MySingleton {
private static MySingleton instance;
private static Context ctx;
private RequestQueue requestQueue;
private ImageLoader imageLoader;
private MySingleton(Context context) {
ctx = context;
requestQueue = getRequestQueue();
imageLoader = new ImageLoader(requestQueue,
new ImageLoader.ImageCache() {
private final LruCache<String, Bitmap>
cache = new LruCache<String, Bitmap>(20);
@Override
public Bitmap getBitmap(String url) {
return cache.get(url);
}
@Override
public void putBitmap(String url, Bitmap bitmap) {
cache.put(url, bitmap);
}
});
}
public static synchronized MySingleton getInstance(Context context) {
if (instance == null) {
instance = new MySingleton(context);
}
return instance;
}
public RequestQueue getRequestQueue() {
if (requestQueue == null) {
requestQueue = Volley.newRequestQueue(ctx.getApplicationContext());
}
return requestQueue;
}
public <T> void addToRequestQueue(Request<T> req) {
getRequestQueue().add(req);
}
public ImageLoader getImageLoader() {
return imageLoader;
}
}
调用方式:
RequestQueue queue = MySingleton.getInstance(this.getApplicationContext()).getRequestQueue();
MySingleton.getInstance(this).addToRequestQueue(stringRequest);
4、volley预置的请求类型;
<1>.Volley 支持的常见请求类型: StringRequest :获取字符串 JsonObjectRequest 和JsonArrayRequest (JsonRequest 的两个子类):获取JSON对象或数组
<2>.Volley为JSON请求提供了以下类: JsonArrayRequest :获取数组 JsonObjectRequest :获取对象并允许传入可选的JSONObject作为请求正文的一部分。 代码:
String url = "http://mythsun-json";
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest (Request.Method.GET, url, null,
new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
textView.setText("Response: " + response.toString());
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
}
});
MySingleton.getInstance(this).addToRequestQueue(jsonObjectRequest);
5、自定义请求类型;
<1>. 如果需要字符串、图片或JSON,那么不需要实现自定义Request 自定义思路: 继承Request类,其中表示请求期望的类型。如果已解析的响应是字符串,继承Request创建自定义请求。 实现抽象方法parseNetworkResponse()和deliverResponse()【包装和发送】, 代码:
@Override
protected Response<T> parseNetworkResponse(NetworkResponse response) {
try {
String json = new String(response.data,
HttpHeaderParser.parseCharset(response.headers));
return Response.success(gson.fromJson(json, clazz),HttpHeaderParser.parseCacheHeaders(response));
}
}
注意: parseNetworkResponse()将NetworkResponse 作为其参数,其中包含正常响应的信息如HTTP 状态代码、响应标头等。 实现必须返回Response,其中包含响应对象或错误。 Volley从工作线程调用 parseNetworkResponse()。这样可确保开销大的解析操作(例如将 JPEG 解码为位图)不会阻止界面线程。
<2>. 如果协议具有非标准缓存语义,可以自行构建一个Cache.Entry,但大多数请求都支持下述示例:
return Response.success(myDecodedObject,HttpHeaderParser.parseCacheHeaders(response));
<3>. Volley 使用您在 parseNetworkResponse() 中返回的对象在主线程上进行回调。大多数请求都会在这里调用回调接口
protected void deliverResponse(T response) {
listener.onResponse(response);
}
<4>.GsonRequest GSON是一个内容库,使用反射功能在Java对象和JSON之间来回转换。 可以定义与其对应JSON密钥具有相同名称的Java对象,向GSON传递类对象,而GSON会自动填充字段。 代码:
public class GsonRequest<T> extends Request<T> {
private final Gson gson = new Gson();
private final Class<T> clazz;
private final Map<String, String> headers;
private final Listener<T> listener;
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
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));
return Response.success(gson.fromJson(json, clazz),HttpHeaderParser.parseCacheHeaders(response));
} catch (UnsupportedEncodingException e) {
return Response.error(new ParseError(e));
} catch (JsonSyntaxException e) {
return Response.error(new ParseError(e));
}
}
}
有用的话,麻烦点个赞~
|