zoukankan      html  css  js  c++  java
  • 开源框架Volley的使用《一》

    转载本专栏每一篇博客请注明转载出处地址,尊重原创。此博客转载链接地址:小杨的博客 http://blog.csdn.net/qq_32059827/article/details/52785378

    本篇对一个开源框架Volley的使用做一个汇总。概述如下:

    Volley

    • 回忆xutils:快速开发型框架,DbUtils(orm),ViewUtils(ioc),HttpUtils,BitmapUtils
    • 其他的快速开发型框架:andBase,thinkandroid,loonandroid,dhroid
    • orm:对象关系型映射
      • db:create table ttable(id integer primary key autoincret...);
      • insert-->save(obj)
    • ioc:控制反转
      • Obj obj = new Obj();
      • 对象的实例化,不用new关键字就可以了吧.
    • 为什么要讲volley?
      • 因为它是google出的,google 在2013 i/o大会上提出来的.
      • 而且在几个项目里面已经看到了它的身影
    • google公司为什么会去搞一个volley框架?
      • 1. 用户开启一个activity,然后加载网络,这个时候.如果用户点击了finish按钮.activity被销毁了-->网络请求和activity的生命周期是应该联动起来的.
      • 2. listview加载图片的情况比较多.如果用户快速的去滑动listview-->getView->快速的加载图片,用户停止操作的时候.其实真正现实的图片最多就几张--->图片应该缓存起来(内存 +本地 )
      • 3. 如果用户打开了一个activity,用户旋转了一下屏幕.activity会旋转-->生命周期重走了-->网络请求缓存
      • 4. 之前我们的网络请求,httpurlconnection,httpclient,asynctask(api)-->android sdk-->封装性不够好.1000个开发者就有1000种使用方式-->不够统一
      • 5. 理念很容易理解,是开源的.
    • volley是啥?
      • 是一种通信框架,和xutils中的HttpUtils,BitmapUtils

    Volley两个核心类

    • RequestQueue 用来执行请求的请求队列
    • Request 用来构造一个请求对象
    • Request对象主要有以下几种类型: 
      1. StringRequest 响应的主体为字符串
      2. JsonArrayRequest 发送和接收JSON数组
      3. JsonObjectRequest 发送和接收JSON对象
      4. ImageRequest 发送和接收Image

    • Request:一个请求
      • StringRequest:请求的时候直接回来一个String
      • JsonObjectRequest:请求的时候直接回来一个JsonObject
      • JsonArrayRequest:请求的时候直接回来一个JsonArray
      • ImageRequest:请求的时候直接回来一个Bitmap
      • 自定义请求:一会我们会结合gson
    • ImageLoader:图片的加载器
    • NetWorkImageView:继承了imageView,对ImageView进行了拓展
    • RequestQueue:请求队列

    Volley到底有哪些特点呢?

    1. 自动调度网络请求
    2. 多个并发的网络连接
    3. 通过使用标准的HTTP缓存机制保持磁盘和内存响应的一致
    4. 支持请求优先级
    5. 支持取消请求的强大API,可以取消单个请求或多个
    6. 易于定制
    7. 健壮性:便于正确的更新UI和获取数据
    8. 包含调试和追踪工具



    接下来就一一对其使用方式做一个汇总。

    1、StringRequest的使用,代码如下:

    package com.example.volleydemo;
    
    import android.app.Activity;
    import android.os.Bundle;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.widget.Button;
    
    import com.android.volley.RequestQueue;
    import com.android.volley.Response;
    import com.android.volley.Response.Listener;
    import com.android.volley.VolleyError;
    import com.android.volley.toolbox.StringRequest;
    import com.android.volley.toolbox.Volley;
    
    public class MainActivity extends Activity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            initStringRequest();
        }
    
        /**
         * StringRequest使用
         */
    	private void initStringRequest() {
    		Button btn1 = (Button) findViewById(R.id.btn1);
    		btn1.setOnClickListener(new OnClickListener() {
    			
    			@Override
    			public void onClick(View v) {
    				//1、创建StringRequest对象
    				String url = "http://www.baidu.com";
    				StringRequest stringRequest = new StringRequest(url , new Listener<String>() {
    
    					@Override
    					public void onResponse(String response) {
    						// 请求成功回调
    						System.out.println("success---->>"+response);
    					}
    				}, new Response.ErrorListener() {
    
    					@Override
    					public void onErrorResponse(VolleyError error) {
    						// 失败回调
    						System.out.println("error---->>"+error);
    					}
    				});
    				//2、创建requestQueue
    				RequestQueue requestQueue = Volley.newRequestQueue(MainActivity.this);
    				//3、发起网络请求----》把reuest防盗requestqueue中
    				requestQueue.add(stringRequest);
    			}
    		});
    	}
    }
    

    其实和httputils差不多。

    2、JsonObjectRwquest的使用

    请求服务器。直接返回一个数据的jsonObject对象

    /**
         * JsonObjectRequest的使用
         */
        private void initJsonObjectRequest() {
        	findViewById(R.id.btn2).setOnClickListener(new OnClickListener() {
    			
    			@Override
    			public void onClick(View v) {
    				//1、创建JsonObjectRequest对象
    				String url = "http://192.168.1.100:8080/getviruses.json";
    				JSONObject jsonRequest = null;//表示post请求,直接post一个jsonobject
    				JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(url , jsonRequest , new Listener<JSONObject>() {
    
    					@Override
    					public void onResponse(JSONObject response) {
    						//从jsonobject获取数据
    						String desc = response.optString("md5");//不需要捕获异常的api
    						System.out.println("success---->>"+desc);
    					}
    				}, new Response.ErrorListener() {
    
    					@Override
    					public void onErrorResponse(VolleyError error) {
    						System.out.println(error);
    					}
    				});
    				//2、创建requestQueue
    				RequestQueue queue = Volley.newRequestQueue(MainActivity.this);
    				//3、发起网络请求----》把reuest放到requestqueue中
    				queue.add(jsonObjectRequest);
    			}
    		});
        }
    其中有一个小知识点,很少知道:即:response.optString("origin");

    JsonObject取值

    • String origin = response.getString("origin");// 方式一
      • 这个如果没有对应的key会抛异常.需要异常处理
    • String origin = response.optString("origin");// 方式二
      • 这个如果没有对应的key不会抛异常.会返回一个默认值
      • optString:默认值""
      • optInt:默认值 0
      • 比如有的实体bean属性很多.我们不喜欢去建议对应的XXX.class的时候.可以使用JsonObject里面的这个方法

    3、JsonArrayRequest的使用

    请求服务器。直接返回一个数据的jsonArrayt对象。和2非常接近。只不过是把Object换成Array。稍作修改罢了。

    4、ImageRequest的使用

     /**
         * ImageRequest的使用
         */
        private void initImageRequest() {
        	findViewById(R.id.btn3).setOnClickListener(new OnClickListener() {
    			
    			@Override
    			public void onClick(View v) {
    				String url = "http://192.168.1.100:8080/meinv.jpg";
    				ImageRequest imageRequest = new ImageRequest(url , new Listener<Bitmap>() {
    
    					@Override
    					public void onResponse(Bitmap response) {
    						iv.setImageBitmap(response);
    					}
    				}, 0, 0, Bitmap.Config.ARGB_4444, new Response.ErrorListener() {
    
    					@Override
    					public void onErrorResponse(VolleyError error) {
    						
    					}
    				});
    				//2、创建requestQueue
    				RequestQueue queue = Volley.newRequestQueue(MainActivity.this);
    				//3、发起网络请求----》把reuest放到requestqueue中
    				queue.add(imageRequest);
    			}
    		});
    	}

    到这里,可能就要详细说明上边代码意义了。加载图片,不想前面三种简单,这里还是有许多学问的。那么,就从源码的角度,从0开始来分析这里的原理。

    4.1 使用步骤

    ImageRequest仍旧是一个request对象,所以使用方式和StringRequest、JsonObjectRequest、JsonArrayRequest十分相似。

    步骤:

    1. 建立一个RequestQueue对象
    2. 建立一个ImageRequest对象
    3. 将ImageRequest添加到RequestQueue中

    第一步、第三步我们在上篇文章中已经做好了,如果不清楚的话可以去上一篇文章查看。

    4.2 分析构造函数

    源码中的构造函数是这样定义的:

     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;
        }

    默认的请求方式是GET,初始化方法需要传入:图片的url,一个响应结果监听器,图片的最大宽度,图片的最大高度,图片的颜色属性,出错响应的监听器。

    说明:图片的颜色属性,Bitmap.Config下的几个常量都可以在这里使用,其中ARGB_8888可以展示最好的颜色属性,每个图片像素占据4个字节的大小,而RGB_565则表示每个图片像素占据2个字节大小


    /** Socket timeout in milliseconds for image requests */
        private static final int IMAGE_TIMEOUT_MS = 1000;
    
        /** Default number of retries for image requests */
        private static final int IMAGE_MAX_RETRIES = 2;
    
        /** Default backoff multiplier for image requests */
        private static final float IMAGE_BACKOFF_MULT = 2f;

    • 设定超时时间:1000ms;
    • 最大的请求次数:2次;
    • 发生冲突时的重传延迟增加数:2f(这个应该和TCP协议有关,冲突时需要退避一段时间,然后再次请求);

    4.3 解释maxWidth,maxHeight参数

    注释中详细说明了图片宽高的意义和作用,为了便于理解我再详细说一下。

    先来完整解释下注释的意思:

    • 建立一个请求对象,按照最大宽高进行解码 。
    • 如果设定的宽和高都是0,那么下载到的图片将会按照实际的大小进行解码,也就是不压缩。
    • 如果宽和高中的一个或两个值不为0,那么图片的宽/高(取决于你设定了宽还是高)会压缩至设定好的值,而另一个宽/高将会按原始比例改变。
    • 如果宽和高都不是0,那么得到的图片将会“按比例”解码到你设定的宽高,也就是说最终得到的图片大小不一定是你最初设定的大小。

    举个例子:

    我的图片原本像素是:850x1200.

    maxWidth = 0,maxHeight = 0时,最终得到的bitmap的宽高是850x1200

    当maxWidth = 0,maxHeight = 600时,得到的bitmap是425x600.这就说明它会按照一个不为0的边的值,将图片进行等比缩放。

    当maxWidth = 100,maxHeight = 600时,我们得到的bitmap竟然是100x141,是按照100进行等比缩小后的图片,而不是100x600.

    这是因为源码中,当宽高分别缩放后,会按照缩放比例大的哪个比例去缩放。就是上边第三种情况:宽缩小8.5倍,高也按照这个比例去缩放。


  • 相关阅读:
    Codeforces F. Bits And Pieces(位运算)
    一场comet常规赛的台前幕后
    【NOIP2019模拟2019.9.4】B(期望的线性性)
    「NOI2016」循环之美(小性质+min_25筛)
    【NOI2011】兔农(循环节)
    LOJ #6538. 烷基计数 加强版 加强版(生成函数,burnside引理,多项式牛顿迭代)
    noi2019感想
    7.12模拟T2(套路容斥+多项式求逆)
    CF 848E(动态规划+分治NTT)
    CF 398 E(动态规划)
  • 原文地址:https://www.cnblogs.com/wanghang/p/6299572.html
Copyright © 2011-2022 走看看