IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> volley详解以及用法 -> 正文阅读

[网络协议]volley详解以及用法

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; // Assume this exists.
RequestQueue requestQueue;  // Assume this exists.
// Set the tag on the request.
stringRequest.setTag(TAG);
// Add the request to the RequestQueue.
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;
// Instantiate the cache
Cache cache = new DiskBasedCache(getCacheDir(), 1024 * 1024); // 1MB cap
// Set up the network to use HttpURLConnection as the HTTP client.
Network network = new BasicNetwork(new HurlStack());
// Instantiate the RequestQueue with the cache and network.
requestQueue = new RequestQueue(cache, network);
// Start the queue
requestQueue.start();
String url ="http://www.mythsun.com";
// Formulate the request and handle the response.
StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
        new Response.Listener<String>() {
    @Override
    public void onResponse(String response) {
        // Do something with the response
    }
},
    new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            // Handle error
    }
});
// Add the request to the RequestQueue.
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并初始化一个缓存
        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) {
            // getApplicationContext() is key, it keeps you from leaking the
            // Activity or BroadcastReceiver if someone passes one in.
            requestQueue = Volley.newRequestQueue(ctx.getApplicationContext());
        }
        return requestQueue;
    }

    public <T> void addToRequestQueue(Request<T> req) {
        getRequestQueue().add(req);
    }

    public ImageLoader getImageLoader() {
        return imageLoader;
    }
}

调用方式:

// Get a RequestQueue
RequestQueue queue = MySingleton.getInstance(this.getApplicationContext()).getRequestQueue();
// Add a request (in this example, called stringRequest) to your RequestQueue.
MySingleton.getInstance(this).addToRequestQueue(stringRequest);

4、volley预置的请求类型;

<1>.Volley 支持的常见请求类型:
StringRequest:获取字符串
JsonObjectRequestJsonArrayRequest(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) {
		// TODO: Handle error
	}
});

// Access the RequestQueue through your singleton class.
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));
	}
	// handle errors
}

注意:
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> {	// 继承Request<T>
	private final Gson gson = new Gson();
	private final Class<T> clazz;
	private final Map<String, String> headers;
	private final Listener<T> listener;

	/**
	 * 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(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));
		}
	}
}

有用的话,麻烦点个赞~

  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2021-09-04 17:54:21  更:2021-09-04 17:55:47 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/19 20:24:37-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码