• Android热门网络框架Volley详解


    .Volley简介

    volley的英文意思为‘群发’、‘迸发’。Volley是2013年谷歌官方发布的一款Android平台上的网络通信库。Volley非常适合一些数据量不大,但需要频繁通信的网络操作。使用Volley进行网络开发可以使我们的开发效率得到很大的提升,而且性能的稳定性也比较高。但是Volley不适用于文件的上传下载操作。

    Volley的特点:

    >1 使网络通信更快,更简单,更健壮;

    >2 Get/Post网络请求及网络图像的高效率异步请求;  

    >3 可以对网络请求的优先级进行排序处理;

    >4 可以进行网络请求的缓存;

    >5 可以取消多级别请求;

    >6 可以和Activity生命周期联动。

    为什么要使用Volley?

    功能上:

    高效的Get/Post方式的数据请求交互;

    网络图片的加载和缓存过程简单化。

    其他:

    谷歌官方推出的,比较权威;

    性能很稳定、强劲。

    .使用Volley

    1.Volley的网络请求队列建立与取消队列请求

    使用Volley需要建立一个全局的请求队列,这样我们就可以将一个请求加入到这个全局队列中,并可以管理整个APP的所有请求,包括取消一个或所有的请求。

    2.Volley的Get和Post请求方式的使用

    Volley的Get和Post请求方式其实是对Android原生Get和Post请求方式进行了二次封装,对效率等进行优化。在使用Get和Post请求方式之前,我们要确定所请求的数据返回什么对象,Volley自带了三种返回类型:

    StringRequest:主要使用在对请求数据的返回类型不确定的情况下,StringRequest涵盖了JsonObjectRequest和JsonArrayRequest。

    JsonObjectRequest:当确定请求数据的返回类型为JsonObject时使用。

    JsonArrayRequest:当确定请求数据的返回类型为JsonArray时使用。

    3.Volley与Activity生命周期的联动

    简单来说就是Volley中的请求是与Activity的生命周期进行关联。这样可以在Android销毁时关闭Volley的请求,防止请求在后台运行造成内存溢出等情况发生。与Activity生命周期进行联动时需要设置Tag标签,因为取消请求需要在请求队列中通过Tag标签进行查找,在Activity的onStop中执行取消请求的操作。

    下面通过代码进行实例的演示。

    使用Volley前需要往项目中导入Volley的jar包。没有的可以直接点此下载:volley.jar

    首先我们需要自定义一个Application用于创建一个全局的请求队列。

    MyApplication.java

    复制代码
    public class MyApplication extends Application{
        private static RequestQueue queues ;
        @Override
        public void onCreate() {
            super.onCreate();
            queues = Volley.newRequestQueue(getApplicationContext());
        }
    
        public static RequestQueue getHttpQueues() {
            return queues;
        }
    }
    复制代码

    AndroidManifest.xml

    复制代码
    <?xml version="1.0" encoding="utf-8"?>
    <manifest package="com.cbt.learnvolley"
              xmlns:android="http://schemas.android.com/apk/res/android">
        <!-- 添加网络操作权限 -->
        <uses-permission android:name="android.permission.INTERNET"/>
    
        <!-- 注册自定义的Application:android:name=".MyApplication" -->
        <application
            android:name=".MyApplication"
            android:allowBackup="true"
            android:icon="@mipmap/ic_launcher"
            android:label="@string/app_name"
            android:supportsRtl="true"
            android:theme="@style/AppTheme">
            <activity android:name=".MainActivity">
                <intent-filter>
                    <action android:name="android.intent.action.MAIN"/>
    
                    <category android:name="android.intent.category.LAUNCHER"/>
                </intent-filter>
            </activity>
        </application>
    
    </manifest>
    复制代码

    .使用Get方式请求数据返回StringRequest对象

    当想返回String类型的请求结果数据或者不清楚返回什么类型时可以用StringRequest对象。

    下面使用Get请求方式返回一个String类型的手机归属地信息。

    MainActivity.java

    复制代码
    public class MainActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            volleyGet();
        }
    
        /**
         *  new StringRequest(int method,String url,Listener listener,ErrorListener errorListener)
         *  method:请求方式,Get请求为Method.GET,Post请求为Method.POST
         *  url:请求地址
         *  listener:请求成功后的回调
         *  errorListener:请求失败的回调
         */
        private void volleyGet() {
            String url = "https://tcc.taobao.com/cc/json/mobile_tel_segment.htm?tel=15850781443";
            StringRequest request = new StringRequest(Method.GET, url,
                    new Listener<String>() {
                        @Override
                        public void onResponse(String s) {//s为请求返回的字符串数据
                            Toast.makeText(MainActivity.this,s,Toast.LENGTH_LONG).show();
                        }
                    },
                    new ErrorListener() {
                        @Override
                        public void onErrorResponse(VolleyError volleyError) {
                            Toast.makeText(MainActivity.this,volleyError.toString(),Toast.LENGTH_LONG).show();
                        }
                    });
            //设置请求的Tag标签,可以在全局请求队列中通过Tag标签进行请求的查找
            request.setTag("testGet");
            //将请求加入全局队列中
            MyApplication.getHttpQueues().add(request);
        }
    
    }
    复制代码

    运行结果:

    .使用Get方式请求数据返回JsonObjectRequest对象

    由于我们知道这个请求返回的是Json格式的数据,所以我们可以直接使用JsonObjectRequest作为请求返回结果对象。

    下面使用Get请求方式返回一个Json格式的IP地址信息,这里只是展示一下返回的数据信息,具体的Json解析方法大家可自行研究。

    复制代码
    /**
     *  new JsonObjectRequest(int method,String url,JsonObject jsonObject,Listener listener,ErrorListener errorListener)
     *  method:请求方式,Get请求为Method.GET,Post请求为Method.POST
     *  url:请求地址
     *  JsonObject:Json格式的请求参数。如果使用的是Get请求方式,请求参数已经包含在url中,所以可以将此参数置为null
     *  listener:请求成功后的回调
     *  errorListener:请求失败的回调
     */
    private void volleyGet() {
        String url = "http://int.dpool.sina.com.cn/iplookup/iplookup.php?format=json&ip=218.4.255.255";
        JsonObjectRequest request = new JsonObjectRequest(Method.GET, url, null,
                new Listener<JSONObject>() {
                    @Override
                    public void onResponse(JSONObject jsonObject) {//jsonObject为请求返回的Json格式数据
                        Toast.makeText(MainActivity.this,jsonObject.toString(),Toast.LENGTH_LONG).show();
                    }
                },
                new ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError volleyError) {
                        Toast.makeText(MainActivity.this,volleyError.toString(),Toast.LENGTH_LONG).show();
                    }
                });
    
        //设置请求的Tag标签,可以在全局请求队列中通过Tag标签进行请求的查找
        request.setTag("testGet");
        //将请求加入全局队列中
        MyApplication.getHttpQueues().add(request);
    }
    复制代码

    运行结果:

    返回JsonArrayRequest对象的方法与JsonObjectRequest比较类似,这里就不再演示,请大家自行实现。

    .使用Post方式请求数据返回StringRequest对象

    使用Post方式需要手动传递请求参数,可以重写Request类的getParams()方法将请求参数名和参数值放入Map中进行传递。

    MainActivity.java

    复制代码
    public class MainActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            volleyPost();
        }
    
        /**
         * 使用Post方式返回String类型的请求结果数据
         * 
         *  new StringRequest(int method,String url,Listener listener,ErrorListener errorListener)
         *  method:请求方式,Get请求为Method.GET,Post请求为Method.POST
         *  url:请求地址
         *  listener:请求成功后的回调
         *  errorListener:请求失败的回调
         */
        private void volleyPost() {
            String url = "https://tcc.taobao.com/cc/json/mobile_tel_segment.htm";
            StringRequest request = new StringRequest(Method.POST, url,
                    new Listener<String>() {
                        @Override
                        public void onResponse(String s) {//s为请求返回的字符串数据
                            Toast.makeText(MainActivity.this,s,Toast.LENGTH_LONG).show();
                        }
                    },
                    new ErrorListener() {
                        @Override
                        public void onErrorResponse(VolleyError volleyError) {
                            Toast.makeText(MainActivity.this,volleyError.toString(),Toast.LENGTH_LONG).show();
                        }
                    }){
                        @Override
                        protected Map<String, String> getParams() throws AuthFailureError {
                            Map<String,String> map = new HashMap<>();
                            //将请求参数名与参数值放入map中
                            map.put("tel","15850781443");
                            return map;
                        }
                    }
                    ;
            //设置请求的Tag标签,可以在全局请求队列中通过Tag标签进行请求的查找
            request.setTag("testPost");
            //将请求加入全局队列中
            MyApplication.getHttpQueues().add(request);
        }
    }
    复制代码

    .使用Post方式请求数据返回JsonObject对象

    复制代码
    /**
     *  使用Post方式返回JsonObject类型的请求结果数据
     *
     *  new JsonObjectRequest(int method,String url,JsonObject jsonObject,Listener listener,ErrorListener errorListener)
     *  method:请求方式,Get请求为Method.GET,Post请求为Method.POST
     *  url:请求地址
     *  JsonObject:Json格式的请求参数。如果使用的是Get请求方式,请求参数已经包含在url中,所以可以将此参数置为null
     *  listener:请求成功后的回调
     *  errorListener:请求失败的回调
     */
    private void volleyPost() {
        String url = "http://www.kuaidi100.com/query";
        Map<String,String> map = new HashMap<>();
        map.put("type","yuantong");
        map.put("postid","229728279823");
        //将map转化为JSONObject对象
        JSONObject jsonObject = new JSONObject(map);
    
        JsonObjectRequest request = new JsonObjectRequest(Method.POST, url, jsonObject,
                new Listener<JSONObject>() {
                    @Override
                    public void onResponse(JSONObject jsonObject) {//jsonObject为请求返回的Json格式数据
                        Toast.makeText(MainActivity.this,jsonObject.toString(),Toast.LENGTH_LONG).show();
                    }
                },
                new ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError volleyError) {
                        Toast.makeText(MainActivity.this,volleyError.toString(),Toast.LENGTH_LONG).show();
                    }
                });
        //设置请求的Tag标签,可以在全局请求队列中通过Tag标签进行请求的查找
        request.setTag("testPost");
        //将请求加入全局队列中
        MyApplication.getHttpQueues().add(request);
    }
    复制代码

    .与Activity生命周期联动

    可以在Activity关闭时取消请求队列中的请求。

    @Override
    protected void onStop() {
        super.onStop();
        //通过Tag标签取消请求队列中对应的全部请求
        MyApplication.getHttpQueues().cancelAll("abcGet");
    }

    .使用ImageRequest加载网络图片

    MainActivity.java

    复制代码
    public class MainActivity extends AppCompatActivity {
        private ImageView image;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            image = (ImageView) findViewById(R.id.image);
            loadImageByVolley();
        }
    
        /**
         *  通过Volley加载网络图片
         *
         *  new ImageRequest(String url,Listener listener,int maxWidth,int maxHeight,Config decodeConfig,ErrorListener errorListener)
         *  url:请求地址
         *  listener:请求成功后的回调
         *  maxWidth、maxHeight:设置图片的最大宽高,如果均设为0则表示按原尺寸显示
         *  decodeConfig:图片像素的储存方式。Config.RGB_565表示每个像素占2个字节,Config.ARGB_8888表示每个像素占4个字节等。
         *  errorListener:请求失败的回调
         */
        private void loadImageByVolley() {
            String url = "http://pic20.nipic.com/20120409/9188247_091601398179_2.jpg";
            ImageRequest request = new ImageRequest(
                                url,
                                new Listener<Bitmap>() {
                                    @Override
                                    public void onResponse(Bitmap bitmap) {
                                        image.setImageBitmap(bitmap);
                                    }
                                },
                                0, 0, Config.RGB_565,
                                new ErrorListener() {
                                    @Override
                                    public void onErrorResponse(VolleyError volleyError) {
                                        image.setImageResource(R.mipmap.ic_launcher);
                                    }
                                });
    
            //设置请求的Tag标签,可以在全局请求队列中通过Tag标签进行请求的查找
            request.setTag("loadImage");
            //通过Tag标签取消请求队列中对应的全部请求
            MyApplication.getHttpQueues().add(request);
        }
    
    }
    复制代码

    运行结果:

    .使用ImageLoader加载及缓存网络图片

    MainActivity.java

    复制代码
    public class MainActivity extends AppCompatActivity {
        private ImageView image;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            image = (ImageView) findViewById(R.id.image);
            loadImageWithCache();
        }
    /**
         *  通过ImageLoader加载及缓存网络图片
       * * new ImageLoader(RequestQueue queue,ImageCache imageCache) * queue:请求队列 * imageCache:一个用于图片缓存的接口,一般需要传入它的实现类 * * getImageListener(ImageView view, int defaultImageResId, int errorImageResId) * view:ImageView对象 * defaultImageResId:默认的图片的资源Id * errorImageResId:网络图片加载失败时显示的图片的资源Id */ private void loadImageWithCache() { String url = "http://pic20.nipic.com/20120409/9188247_091601398179_2.jpg"; ImageLoader loader = new ImageLoader(MyApplication.getHttpQueues(), new BitmapCache()); ImageListener listener = loader.getImageListener(image,R.mipmap.ic_launcher,R.mipmap.ic_launcher); //加载及缓存网络图片 loader.get(url,listener); } }
    复制代码

    BitmapCache.java

    复制代码
    public class BitmapCache implements ImageLoader.ImageCache{
        //LruCache是基于内存的缓存类
        private LruCache<String,Bitmap> lruCache;
        //LruCache的最大缓存大小
        private int max = 10 * 1024 * 1024;
    
        public BitmapCache() {
            lruCache = new LruCache<String, Bitmap>(max){
                @Override
                //缓存图片的大小
                protected int sizeOf(String key, Bitmap value) {
                    return value.getRowBytes() * value.getHeight();
                }
            };
        }
    
        @Override
        public Bitmap getBitmap(String s) {
            return lruCache.get(s);
        }
    
        @Override
        public void putBitmap(String s, Bitmap bitmap) {
            lruCache.put(s,bitmap);
        }
    }
    复制代码

    运行结果:

    完整源码:点击下载

     
  • 相关阅读:
    根据数组对象中的某个属性值排序
    vue小知识
    vue项目中config文件中的 index.js 配置
    小问题
    原生无缝轮播
    webpack打包提交代码
    echarts
    面试问题
    MySql
    vue-router 跳转原理
  • 原文地址:https://www.cnblogs.com/AceIsSunshineRain/p/5143846.html
Copyright © 2020-2023  润新知