Android网络编程框架推荐-Volley

Volley是Google于2013年推出的网络通信框架,集AsyncHttpClient和Universal-Image-Loader的优点于一身,对于数据量不大且需要频繁通信的网络请求操作可谓是及时雨,他的扩展性也非常好,可以重写Request类以实现自己的需求,所以非常推荐大家在合适的情景下使用这个框架。
Volley的官方地址:https://android.googlesource.com/platform/frameworks/volley
我使用的是git上面2015年8月份提交的代码。

下面详细介绍Volley的使用方法

1.工具类VolleyUtils,里面主要包含了String类型、JSON类型以及图片的Http请求方法总共7种,详细如下:
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import com.android.volley.AuthFailureError;
import com.android.volley.Request.Method;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.ImageLoader;
import com.android.volley.toolbox.ImageLoader.ImageListener;
import com.android.volley.toolbox.JsonArrayRequest;
import com.android.volley.toolbox.JsonObjectRequest;
import com.android.volley.toolbox.StringRequest;
import com.google.gson.Gson;
import com.google.gson.JsonSyntaxException;
import com.google.gson.reflect.TypeToken;

import android.content.Context;
import android.widget.ImageView;

/**
 * 代理模式,也可以作为Model(MVC),具体方法自行添加
 * 
 * @author gaoruan
 */
public class VolleyUtils {
    private static VolleyUtils volleyUtils;
    private static RequestQueue requestQueue;
    private static Context mContext;

    public VolleyUtils() {
        // TODO Auto-generated constructor stub

    }

    public static VolleyUtils getInstance(Context mContext, RequestQueue requestQueue) {
        VolleyUtils.mContext = mContext;
        VolleyUtils.requestQueue = requestQueue;
        if (volleyUtils == null) {
            volleyUtils = new VolleyUtils();
        }
        return volleyUtils;
    }

    // 字符串类型GET
    public static StringRequest sHttpGet(String url) {
        StringRequest stringRequest = new StringRequest(url, new Response.Listener<String>() {

            @Override
            public void onResponse(String arg0) {
                // TODO Auto-generated method stub
                LogUtils.e(arg0);
            }
        }, new Response.ErrorListener() {

            @Override
            public void onErrorResponse(VolleyError arg0) {
                // TODO Auto-generated method stub
                LogUtils.e(arg0.getMessage());
            }
        });

        return stringRequest;
    }

    // 字符串类型POST,链接必须支持post方式
    public static StringRequest sHttpPost(String url) {
        // 指定Method.POST当然也可以指定Method.GET
        StringRequest stringRequest = new StringRequest(Method.POST, url, new Response.Listener<String>() {

            @Override
            public void onResponse(String arg0) {
                // TODO Auto-generated method stub
                LogUtils.e(arg0);
            }
        }, new Response.ErrorListener() {

            @Override
            public void onErrorResponse(VolleyError arg0) {
                // TODO Auto-generated method stub

                LogUtils.e(arg0.getMessage());
            }
        }) {
            // 设置post参数
            @Override
            protected Map<String, String> getParams() throws AuthFailureError {
                // TODO Auto-generated method stub
                Map<String, String> map = new HashMap<String, String>();
                map.put("key", "value");
                return super.getParams();
            }
        };

        return stringRequest;
    }

    // JsonObject类型GET
    public static JsonObjectRequest jsonoHttpGet(String url) {
        JSONObject jsonObject = new JSONObject();
        //
        // if (jsonObject == null) {
        // // 默认为get方式
        // } else {
        // // 默认为post方式
        // }
        //

        // 此处使用GET方式发送请求
        jsonObject = null;
        JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(url, jsonObject,
                new Response.Listener<JSONObject>() {

                    @Override
                    public void onResponse(JSONObject arg0) {
                        // TODO Auto-generated method stub
                        List<MWeather> list = new ArrayList<MWeather>();
                        Type type = new TypeToken<List<MWeather>>() {
                        }.getType();
                        Gson gson = new Gson();
                        try {
                            list = gson.fromJson(arg0.getJSONObject("data").getJSONArray("forecast").toString(), type);
                        } catch (JsonSyntaxException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        } catch (JSONException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }

                        String mWeathers = gson.toJson(list);
                        LogUtils.e(mWeathers);

                    }
                }, new Response.ErrorListener() {

                    @Override
                    public void onErrorResponse(VolleyError arg0) {
                        // TODO Auto-generated method stub
                        LogUtils.e(arg0.getMessage());
                    }
                });

        return jsonObjectRequest;
    }

    // JsonObject类型POST,链接必须支持post方式
    public static JsonObjectRequest jsonoHttpPost(String url) throws JSONException {
        // 此处的jsonObject被指定为post参数
        MWeather mWeather = new MWeather();
        mWeather.setCitykey("101010100");
        // 搭配GSON非常好用
        Gson gson = new Gson();
        String mJson = gson.toJson(mWeather);
        // LogUtils.e(mJson);
        // 指定Method.POST当然也可以指定Method.GET
        JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Method.POST, url, new JSONObject(mJson),
                new Response.Listener<JSONObject>() {

                    @Override
                    public void onResponse(JSONObject arg0) {
                        // TODO Auto-generated method stub
                        LogUtils.e(arg0.toString());
                    }
                }, new Response.ErrorListener() {

                    @Override
                    public void onErrorResponse(VolleyError arg0) {
                        // TODO Auto-generated method stub
                        LogUtils.e(arg0.getMessage());
                    }
                });

        return jsonObjectRequest;
    }

    // JsonArray类型GET
    public static JsonArrayRequest jsonaHttpGet(String url) {

        JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(url, new Response.Listener<JSONArray>() {

            @Override
            public void onResponse(JSONArray arg0) {
                // 必须返回JSONArray
                LogUtils.e(arg0.toString());
            }
        }, new Response.ErrorListener() {

            @Override
            public void onErrorResponse(VolleyError arg0) {
                // TODO Auto-generated method stub
                LogUtils.e(arg0.getMessage());
            }
        });

        return jsonArrayRequest;
    }

    // JsonArray类型POST,链接必须支持post方式
    public static JsonArrayRequest jsonaHttpPost(String url) throws JSONException {
        // 此处的jsonObject被指定为post参数
        MWeather mWeather = new MWeather();
        mWeather.setCitykey("101010100");
        // 搭配GSON非常好用
        Gson gson = new Gson();
        String mJson = gson.toJson(mWeather);

        JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(Method.POST, url, new JSONArray(mJson),
                new Response.Listener<JSONArray>() {

                    @Override
                    public void onResponse(JSONArray arg0) {
                        // TODO Auto-generated method stub
                        // 必须返回JSONArray
                        LogUtils.e(arg0.toString());
                    }
                }, new Response.ErrorListener() {

                    @Override
                    public void onErrorResponse(VolleyError arg0) {
                        // TODO Auto-generated method stub
                        LogUtils.e(arg0.getMessage());
                    }

                });

        return jsonArrayRequest;
    }

    public static ImageListener imageHttp(ImageView view, int defaultImageResId, int errorImageResId) {

        ImageListener imageListener = ImageLoader.getImageListener(view, defaultImageResId, errorImageResId);

        return imageListener;

    }

}
2.工具类MImageCache,这个类是ImageLoader加载网络图片用到的一个图片缓存类,继承自com.android.volley.toolbox.ImageLoader.ImageCache,详细如下:
import com.android.volley.toolbox.ImageLoader.ImageCache;

import android.graphics.Bitmap;
import android.support.v4.util.LruCache;

public class MImageCache implements ImageCache {

    private LruCache<String, Bitmap> cache;

    public MImageCache() {
        cache = new LruCache<String, Bitmap>(8 * 1024 * 1024) {
            @Override
            protected int sizeOf(String key, Bitmap bitmap) {
                return bitmap.getRowBytes() * bitmap.getHeight();
            }
        };
    }

    @Override
    public Bitmap getBitmap(String arg0) {
        // TODO Auto-generated method stub
        return cache.get(arg0);
    }

    @Override
    public void putBitmap(String arg0, Bitmap arg1) {
        // TODO Auto-generated method stub
        cache.put(arg0, arg1);
    }

}
3.工具类LogUtils,这个类是自定义的一个log日志类,详细如下:

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Date;

import android.annotation.SuppressLint;
import android.util.Log;

public class LogUtils {
    private final static String TAG = "msg";
    private final static boolean isDebug = true;
    private final static boolean isWF = false;
    @SuppressLint("SdCardPath")
    final static String sdcard = "/mnt/sdcard/";
    final static String logFile = "syslog.txt";
    final static File file = new File(sdcard);

    @SuppressWarnings("deprecation")
    static private void writeToFile(String str) {
        if (isWF)
            return;
        try {
            synchronized (file) {
                if (file.canWrite()) {
                    Date curDate = new Date(System.currentTimeMillis());
                    FileWriter fileWriter = new FileWriter(sdcard + logFile, true);
                    fileWriter
                            .write(curDate.getHours() + ":" + curDate.getMinutes() + ":" + curDate.getSeconds() + " ");
                    fileWriter.write(str + "\n");
                    fileWriter.flush();
                    fileWriter.close();
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private static String StackTrace(int n) {
        // long id = Thread.currentThread().getId();
        String file = Thread.currentThread().getStackTrace()[4 + n].getFileName();
        int line = Thread.currentThread().getStackTrace()[4 + n].getLineNumber();
        String method = Thread.currentThread().getStackTrace()[4 + n].getMethodName();
        return file + "->" + method + " " + ":" + line + " ";
    }

    static public void d(String msg, int n) {
        if (isDebug) {
            String log = StackTrace(n) + msg;
            Log.d(TAG, log);
            writeToFile(log);
        }
    }

    static public void d(String msg) {
        if (isDebug) {
            String log = StackTrace(0) + msg;
            Log.d(TAG, log);
            writeToFile(log);
        }
    }

    static public void i(String msg) {
        if (isDebug) {
            String log = StackTrace(0) + msg;
            Log.i(TAG, log);
            writeToFile(log);
        }
    }

    static public void e(String msg) {
        if (isDebug) {
            String log = StackTrace(0) + msg;
            Log.e(TAG, log);
            writeToFile(log);
        }
    };
}
4.MWeather类,这个类是自定义的一个JavaBean,主要是解析天气预报网址的Json时用到的,详细如下:

public class MWeather {
    private String citykey;
    private String aqi;
    private String desc;
    private String status;
    private String high;
    private String fl;
    private String date;
    private String low;
    private String type;
    private String fx;
    private String wendu;
    private String ganmao;
    private String city;

    public String getCitykey() {
        return citykey;
    }

    public void setCitykey(String citykey) {
        this.citykey = citykey;
    }

    public String getAqi() {
        return aqi;
    }

    public void setAqi(String aqi) {
        this.aqi = aqi;
    }

    public String getDesc() {
        return desc;
    }

    public void setDesc(String desc) {
        this.desc = desc;
    }

    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }

    public String getHigh() {
        return high;
    }

    public void setHigh(String high) {
        this.high = high;
    }

    public String getFl() {
        return fl;
    }

    public void setFl(String fl) {
        this.fl = fl;
    }

    public String getDate() {
        return date;
    }

    public void setDate(String date) {
        this.date = date;
    }

    public String getLow() {
        return low;
    }

    public void setLow(String low) {
        this.low = low;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public String getFx() {
        return fx;
    }

    public void setFx(String fx) {
        this.fx = fx;
    }

    public String getWendu() {
        return wendu;
    }

    public void setWendu(String wendu) {
        this.wendu = wendu;
    }

    public String getGanmao() {
        return ganmao;
    }

    public void setGanmao(String ganmao) {
        this.ganmao = ganmao;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    @Override
    public String toString() {
        return "MWeather [citykey=" + citykey + ", aqi=" + aqi + ", desc=" + desc + ", status=" + status + ", high="
                + high + ", fl=" + fl + ", date=" + date + ", low=" + low + ", type=" + type + ", fx=" + fx + ", wendu="
                + wendu + ", ganmao=" + ganmao + ", city=" + city + "]";
    }

}
5.MainActivity类,这个类是主Activity,主要是调用工具类里面的方法,详细如下:
import com.android.volley.RequestQueue;
import com.android.volley.toolbox.ImageLoader;
import com.android.volley.toolbox.NetworkImageView;
import com.android.volley.toolbox.Volley;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.widget.ImageView;

public class MainActivity extends Activity {
    public static Context mContext;
    private static RequestQueue requestQueue;
    private static ImageLoader imageLoader;
    private ImageView imageView1;
    private NetworkImageView imageView2;
    public static final String MURL = "http://www.battlenet.com.cn/zh/";
    public static final String MWEATHER = "http://wthrcdn.etouch.cn/weather_mini?";// 天气预报
    public static final String CITYKEY = "citykey=101010100";
    // 以下两个网址来自战网
    public static final String IMAGEURLF = "http://cms-origin-cn.battle.net/cms/carousel_header/og/OGBTDYRA7KZB1449121751020.jpg";
    public static final String IMAGEURLS = "http://cms-origin-cn.battle.net/cms/gallery/wf/WFH5OT2327L61446861473547.jpg";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        mContext = this;

        imageView1 = (ImageView) findViewById(R.id.imageView1);
        imageView2 = (NetworkImageView) findViewById(R.id.imageView2);

        VolleyUtils.getInstance(mContext, requestQueue);
        /**
         * 获取String类型response********
         * getRequestQueue().add(VolleyUtils.sHttpGet(MURL));
         * getRequestQueue().add(VolleyUtils.sHttpPost(MURL));
         */

        /**
         * 获取JSONObject类型response
         * getRequestQueue().add(VolleyUtils.jsonoHttpGet(MWEATHER + CITYKEY));
         * getRequestQueue().add(VolleyUtils.jsonoHttpPost(MWEATHER));
         */

        /**
         * 获取JSONArray类型response
         * getRequestQueue().add(VolleyUtils.jsonaHttpGet(MWEATHER + CITYKEY));
         * getRequestQueue().add(VolleyUtils.jsonaHttpPost(MWEATHER));
         */

        /**
         * 获取网络图片********************************************
         * getImageLoader().get(IMAGEURLF, VolleyUtils.imageHttp(imageView1,
         * R.drawable.og_wow, R.drawable.ic_launcher));
         * *******************************************************
         * imageView2.setImageUrl(IMAGEURLS, getImageLoader());
         */

    }

    // 单例
    private RequestQueue getRequestQueue() {
        if (requestQueue == null) {
            requestQueue = Volley.newRequestQueue(mContext);
        }
        return requestQueue;
    }

    // 单例
    private ImageLoader getImageLoader() {

        if (requestQueue == null) {
            requestQueue = Volley.newRequestQueue(mContext);

        }

        if (imageLoader == null) {
            imageLoader = new ImageLoader(getRequestQueue(), new MImageCache());
        }

        return imageLoader;

    }

    @Override
    public void onStop() {
        // 取消未完成的请求
        // mRequestQueue.cancelAll( new RequestFilter() {})
        getRequestQueue().cancelAll(this);
    }
6.Activity用到的xml文件,详细如下:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.ruan.test.MainActivity" >

    <ImageView
        android:id="@+id/imageView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:src="@drawable/ic_launcher" />

    <com.android.volley.toolbox.NetworkImageView
        android:id="@+id/imageView2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/imageView1"
        android:layout_marginTop="50dp"
        android:layout_centerHorizontal="true"
        android:src="@drawable/ic_launcher" />

</RelativeLayout>
总结:

1、需要注意Volley对于JSON格式的返回操作及网络图片加载非常方便,但是并不适合大流量譬如下载、流媒体操作等网络数据量比较大的情景下使用
2、其中RequestQueue和ImageLoader都是单例的,注意尽量不要重复创建
3、Activity销毁的时候需要结束这些请求,因为这些请求都是可控的
4、Volley支持继承Request以实现适合自己项目的网络编程
5、解析JSON的时候用到了GSON封装包,配合Volley非常好用,推荐使用
暂时总结这么多,遇到问题再继续总结。
源码下载:
我是链接,请点我下载

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值