android网络开源框架volley之二

上篇文章简单的介绍了volley的使用,这篇偶将继续和大家一起分享volley的使用。

其实忘记一件很重要的事情,我相信也是很多初识volley的人困惑的地方,就是从哪里开始学习,认识volley,使用volley,可能你谷歌或者百度到的最多的就是一个简单demo或者对volley介绍的翻译,如果你很牛可能理解起来很容易,但是对于我等菜鸟还是有点难度的。虽然偶的水平有限,但是我会尽量遵照自己这段时间对volley的认识过程来总结。


1、volley的部署

上篇提到我们不会直接在Activiy中创建volley的请求队列对象,因为这个对象我们只要一个就够了。既然不这样那我们该怎么做呢,这里给一个建议。先上一张项目结构图:


思路是这样的:我们在application中对volley进行初始化。然后通过静态方法拿到这个对象,即可在所有地方使用,关键代码如下(来自:https://github.com/ogrebgr):

/**
 * 这段代码来自这里:https://github.com/ogrebgr
 * 
 * @author ttdevs
 */
public class VolleyQueue {
	private static RequestQueue mRequestQueue;
	private static ImageLoader mImageLoader;

	private VolleyQueue() {

	}

	/**
	 * 初始化我们的请求队列。这个地方有一个BitmapLruCache,这个是在后面做图片加载的时候会提到的图片缓存策略
	 * 
	 * @param context
	 */
	static void init(Context context) {
		mRequestQueue = Volley.newRequestQueue(context);

		int memClass = ((ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE)).getMemoryClass();
		// Use 1/8th of the available memory for this memory cache.
		int cacheSize = 1024 * 1024 * memClass / 8;
		mImageLoader = new ImageLoader(mRequestQueue, new BitmapLruCache(cacheSize));
	}

	public static RequestQueue getRequestQueue() {
		if (mRequestQueue != null) {
			return mRequestQueue;
		} else {
			throw new IllegalStateException("RequestQueue not initialized");
		}
	}

	public static ImageLoader getImageLoader() {
		if (mImageLoader != null) {
			return mImageLoader;
		} else {
			throw new IllegalStateException("ImageLoader not initialized");
		}
	}
}
这样我们就可以在想要的地方随意使用了。


2、自定义请求

通过第一步拿到请求队列对象之后我们就可肆意的发请求了~~简单的GET请求我们之前已经展示过,下面要说的就是POST方式的请求和自定义自己的请求对象。在此之前,我们先来看一下volley源码的结构,这里也直接上两张图:

红线标注的部分我们看到了熟悉的StringRequest,这个就是我们之前使用的那个请求类。具体源码大家可以去先看一下,这样对下面的代码理解会有很大帮助。
当你简单查看上图的几个*****Request类之后你会发现他们有一个共同的特点:都是继承了Request类。这里先告诉大家,自定义请求类也是继承这个Request类的。我们照着StringRequest类可以得到一个下面的自定义请求类:
public class CustomReqeust extends Request<String> {

	private final Listener<String> mListener;

	public CustomReqeust(int method, String url, Listener<String> listener, ErrorListener errorListener) {
		super(method, url, errorListener);
		mListener = listener;
	}

	@Override
	protected Response<String> parseNetworkResponse(NetworkResponse response) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	protected void deliverResponse(String response) {
		// TODO Auto-generated method stub

	}
}
我们简单的分析下这几行代码。首先是构造函数,通过super我们发现,构造函数中我们需要提供三个参数,分别是:method、url、errorListener,它们的意思分别是:请求方式,即POST/GET;请求的URL;出错时的回调监听器。而StringRequest的构造函数中多了一个Listener<String> listener,这个通过前面的demo大家应该知道它是用来处理请求结果的,当然大部分情况我们是需要这个东西的,因此我们把它加上。这样就完整了。下面还有两个必须实现的方法,这个是干什么的呢?我们先来看看StringRequest中这两个方法的实现:
    @Override
    protected void deliverResponse(String response) {
        mListener.onResponse(response);
    }

    @Override
    protected Response<String> parseNetworkResponse(NetworkResponse response) {
        String parsed;
        try {
            parsed = new String(response.data, HttpHeaderParser.parseCharset(response.headers));
        } catch (UnsupportedEncodingException e) {
            parsed = new String(response.data);
        }
        return Response.success(parsed, HttpHeaderParser.parseCacheHeaders(response));
    }

protected void deliverResponse(String response) {}
传递响应,通过我们初始化时候设置的成功监听器来传递HTTP响应结果。
protected Response<String> parseNetworkResponse(NetworkResponse response){}
通过名称我们猜测是解析网络响应,对StringRequest类源码分析我们大致得出结论它应该是根据HTTP头的编码解析HTTP包体。当我们处理特殊的或者自定义的HTTP请求时就可以在此处实现对HTTP包体进行解析。

说了这么多我们还是没有说到如何进行HTTP的POST请求,因为我们还没讲到如何设置POST方式的请求参数。

自习翻阅volley源码中的几个request类的子类,我们可以在JsonRequest类中发现如下代码:
   /**
     * Returns the raw POST or PUT body to be sent.
     *
     * @throws AuthFailureError in the event of auth failure
     */
    @Override
    public byte[] getBody() {
        try {
            return mRequestBody == null ? null : mRequestBody.getBytes(PROTOCOL_CHARSET);
        } catch (UnsupportedEncodingException uee) {
            VolleyLog.wtf("Unsupported Encoding while trying to get the bytes of %s using %s",
                    mRequestBody, PROTOCOL_CHARSET);
            return null;
        }
    }
对,你猜的没错,他就是处理我们请求参数的方法,在这里我们组织好要传的参数,然后转换成byte数组即可。这样我们就可以开始实现自己自定义的请求了。下面贴一个简单的完整例子供参考:
public class CustomReqeust extends Request<String> {
	/** http请求编码方式 */
	private static final String PROTOCOL_CHARSET = "utf-8";

	private Listener<String> mListener;
	private String mUserName;

	public CustomReqeust(String url, String userName, Listener<String> listener, ErrorListener errorListener) {
		super(Method.POST, url, errorListener);
		mUserName = userName;
		mListener = listener;
	}

	@Override
	protected Response<String> parseNetworkResponse(NetworkResponse response) {
		String parsed;
		try {
			parsed = new String(response.data, HttpHeaderParser.parseCharset(response.headers));
		} catch (UnsupportedEncodingException e) {
			parsed = new String(response.data);
		}
		return Response.success(parsed, HttpHeaderParser.parseCacheHeaders(response));
	}

	@Override
	protected void deliverResponse(String response) {
		mListener.onResponse(response);
	}

	@Override
	public byte[] getBody() {
		try {
			return mUserName == null ? null : mUserName.getBytes(PROTOCOL_CHARSET);
		} catch (UnsupportedEncodingException uee) {
			VolleyLog.wtf("Unsupported Encoding while trying to get the bytes of %s using %s", mUserName, PROTOCOL_CHARSET);
			return null;
		}
	}
}
调用代码不想不贴,但是要用到,还是贴一下(这里的URL还是www.baidu.com):
	private void customRequest() {
		CustomReqeust request = new CustomReqeust(URL, "CustomVolley", new Listener<String>() {

			@Override
			public void onResponse(String arg0) {
				Toast.makeText(getApplicationContext(), arg0, Toast.LENGTH_LONG).show();
				Log.d("onResponse", arg0);
			}
		}, new ErrorListener() {

			@Override
			public void onErrorResponse(VolleyError arg0) {
				Toast.makeText(getApplicationContext(), arg0.toString(), Toast.LENGTH_LONG).show();
				Log.d("onErrorResponse", arg0.toString());
			}
		});
		mQueue.add(request);
	}
由于没有测试服务器,因此就简单的抓包看一下,结果如下:

从图中可以看到,我们的请求时正确的。至此我们就完成了自定义请求的实现。

3、总结

可以自定义的地方远远不止这些,更多的HTTP请求参数大家可以从几个Request子类入手,如JsonRequest类中用到的设置ContentType类型,getRetryPolicy()等。当你了解了这些东西之后你会发现volley真的是高端大气上档次。当然还有很多细节没有讲到,比如取消一个请求,设置请求超时等等,这些细节如果在分析源码的时候遇到会和大家分享。有时间会接着和大家分享volley对图片的加载。从下一篇开始,和大家分享volley的整个架构。最后,有不当之处欢迎吐槽。

后记:

现在时间是1:01分,吐槽两句:代码不是一切,这么晚了还在敲代码还是越少越好,还有更重要的事情等着你。谨此Mark下可能将要失去的坚持了五年的恋爱。最后祝所有的单身程序猿都能找到自己的她……






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Mopria Print Service 2.3推出新的移动打印功能,支持用户使用 安卓设备的“分享”功能进行打印 拓展移动打印功能,方便用户使用其最喜爱的应用程序中的“分享”选项打印照片、文本 、网页等 加州圣拉蒙 – 2017年11月15日– 致力于推动全行业移动打印标准的全球非盈利性会员制组织 Mopria®联盟今日发布Mopria Print Service 2.3,以扩大移动打印支持,允许用户使用诸多最喜爱的 应用程序中的“分享”功能进行打印。此外,Mopria Print Service 2.3还与Android 8.0 Oreo™兼容,后 者的默认打印解决方案采用Mopria核心技术,支持通过1亿多台经Mopria认证的打印机实现轻松移 动打印。所有安卓设备可在Google Play™商店下载其最新版。 Mopria Print Service 2.3利用Facebook、Flipboard、LinkedIn、Twitter和Pinterest等诸多 备受欢迎的应用中现有的“分享”功能,使用户能够轻松打印。当使用“分享”功能时,用户 将看到其中包含Mopria Print Service选项,该选项位于电子邮件和消息选项下方。“分享” 图标位于醒目位置,用户只需选择Mopria Print Service选项、选择打印机、调整设置并 打印即可。 该新版本还支持沿多个方向打孔、折边、装订等分页装订选项,同时提供新界面,新增一 项便于用户快速查看可供使用的打印机并确定其状态的功能。该新界面提供便捷的起点, 方便用户添加或隐藏打印机、访问Mopria设置、排除打印故障以及查看经Mopria认证的 打印机列表。该新界面包含教程,已将这一用户请求最多的功能添加至该项服务中,为新 用户提供移动打印流程指导及建议。 Mopria联盟指导委员会主席Brent Richtsmeier表示:“我们将继续为Mopria Print Service 添加功能,旨在使安卓设备的移动打印体验尽可能轻松便捷。利用全球最受欢迎的应用中 的分享功能中新增的打印选项,用户将重新发现移动打印的便利。” 自发布以来,Mopria Print Service已支持通过安卓智能手机和平板电脑连接经Mopria认 证的打印机实现打印。Mopria Print Service允许用户轻松自定义彩色打印、打印份数、 双面打印、纸张尺寸、页面打印范围、介质类型和打印方向等打印设置,同时还可以定制 用户身份验证、点针式打印和会计功能等工作场所功能,而且不需要安装特定打印机品牌 的应用程序。 自创始人佳能、惠普、三星和施乐成立Mopria联盟以来的四年里,该非盈利性会员制组 织成员已增加至21个,他们代表着全球打印机行业。除创始公司之外,Mopria联盟目前 包括:Adobe、柯尼卡美能达、高通、利盟、京瓷、东芝、Brother、爱普生、富士施乐 、微软、NEC、Pantum、理光、YSoft、夏普、戴尔和致伸科技(Primax)。 Mopria技术目前设备安装数量已超过7亿台,预计不出一年便会超过10亿台。在继续努力 使移动打印变得轻松便捷的同时,Mopria联盟还将进一步专注于云打印和扫描标准化。 Mopria联盟的目标在于促使这些解决方案为消费者和企业用户变得更加方便可及、直观 简便。如需获取经Mopria认证的打印机和打印附件的最新列表,敬请访问: http://mopria.org/certified-products。 关于Mopria®联盟 Mopria®联盟是一个非盈利性会员制组织,由全球领先的科技公司组成,其成立初衷为简 化智能手机、平板电脑和其他设备的打印操作。该联盟制定并推广一系列技术标准,旨在 提供连接不同设备和移动操作系统的直观体验。这些标准的普及使用户能够与各种品牌的 打印机进行无缝交互。此外,对新移动设备或打印机而言,将无需进行应用程序的下载和 安装。利用支持Mopria的移动设备寻找经Mopria认证的打印机和附件实现轻松打印,可 在www.mopria.org了解详情或者在Google Play商店下载最新版Mopria软件。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值