Google开源网络通信库Volley的基本使用

本篇文章主要参考自:http://developer.android.com/training/volley/index.html
  
  按照谷歌官方的说法,Volley主要适用于那些数据量不大,但是通信频繁的场景。这篇文章主要讲些基本用法,关于Volley的具体实现原理,我暂时也没去研究。
  Google推荐用一个单例类来管理Volley的所有网络请求,下面是我目前用到的单例类:

package com.android.etuan.whereru;

import android.content.Context;
import android.graphics.Bitmap;
import android.util.LruCache;

import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.toolbox.ImageLoader;
import com.android.volley.toolbox.Volley;

public class MyVolleySingleton {

    private static MyVolleySingleton mInstance;
    private RequestQueue mRequestQueue;
    private ImageLoader mImageLoader;
    private static Context mContext;

    private MyVolleySingleton(Context context) {
        mContext = context;
        mRequestQueue = getRequestQueue();

        mImageLoader = new ImageLoader(mRequestQueue,
                new ImageLoader.ImageCache() {

                    //谷歌官方推荐的缓存大小计算方式
                    int maxMemory = (int) Runtime.getRuntime().maxMemory() / 1024;
                    int cacheSize = maxMemory / 8;

                    private final LruCache<String, Bitmap>
                            cache = new LruCache<>(cacheSize);

                    @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 MyVolleySingleton getInstance(Context context) {
        if (mInstance == null) {
            mInstance = new MyVolleySingleton(context);
        }
        return mInstance;
    }

    public RequestQueue getRequestQueue() {
        if (mRequestQueue == null) {
            // getApplicationContext() is key, it keeps you from leaking the
            // Activity or BroadcastReceiver if someone passes one in.
            mRequestQueue = Volley.newRequestQueue(mContext.getApplicationContext());
        }
        return mRequestQueue;
    }

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

    public ImageLoader getImageLoader() {
        return mImageLoader;
    }

}

  对于一般APP,get和post足以解决大部分问题了(不过Volley请求的时候好像连Get和Post都不需要指定),下面是我用来请求学校名称列表数据的部分代码(删减了部分相关度不高的代码):  

//下拉列表的数据

mSchoolList = new ArrayList<>();

//请求学校名称数据
JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(
        InterfaceConstant.SCHOOL_NAME_LIST_URL,
        new Response.Listener<JSONArray>() {
            @Override
            public void onResponse(JSONArray jsonArray) {
                mSchoolList = new ArrayList<>();
                for (int i = 0;i < jsonArray.length();i++) {
                    try {
                        mSchoolList.add(jsonArray.getJSONObject(i).getString("name"));
                    } catch (JSONException e) {
                        System.out.println("JSON解析出错 SchoolList");
                    }
                }
            }
        },
        new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError volleyError) {

            }
        });
MyVolleySingleton.getInstance(this.getApplicationContext())
        .addToRequestQueue(jsonArrayRequest);

  就功能实现来说异常简单(当然因为这里要解析的JSON数据很简单,而且数据只在这里用一次,所以直接在这里解析掉了),我目前一般采用的方式如下:

package com.android.etuan.whereru.utils.jsonjavabean;

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

public class Person {

    private static Person sPerson;

    private Person() {
    }

    public static synchronized Person getInstance() {
        if (sPerson == null) {
            sPerson = new Person();
        }
        return sPerson;
    }

    private final String EroMsg = "JSON解析出错 Person";

    private String m_id;
    private int mTtl;
    private String mCreated;
    private String mUserId;
    private String mName;
    private String mSchool;
    private String mPhone;
    private String mSign;

    public String getM_id() {
        return m_id;
    }

    public String getmCreated() {
        return mCreated;
    }

    public int getmTtl() {
        return mTtl;
    }

    public String getmUserId() {
        return mUserId;
    }

    public String getmName() {
        return mName;
    }

    public String getmSchool() {
        return mSchool;
    }

    public String getmPhone() {
        return mPhone;
    }

    public String getmSign() {
        return mSign;
    }


    public void getInfoFromJson(JSONObject jsonObject) {
        try {
            m_id = jsonObject.getString("id");
        } catch (JSONException e) {
            System.out.println(EroMsg + "id");
        }
        try {
            mTtl = jsonObject.getInt("ttl");
        } catch (JSONException e) {
            System.out.println(EroMsg + "ttl");
        }
        try {
            mCreated = jsonObject.getString("created");
        } catch (JSONException e) {
            System.out.println(EroMsg + "created");
        }
        try {
            mUserId = jsonObject.getString("userId");
        } catch (JSONException e) {
            System.out.println(EroMsg + "userId");
        }
        try {
            JSONObject jsonUser = jsonObject.getJSONObject("user");
            try {
                mPhone = jsonUser.getString("phone");
            } catch (JSONException e) {
                System.out.println(EroMsg + "phone");
            }
            try {
                mName = jsonUser.getString("name");
            } catch (JSONException e) {
                System.out.println(EroMsg + "name");
            }
            try {
                mSchool = jsonUser.getString("school");
            } catch (JSONException e) {
                System.out.println(EroMsg + "school");
            }
            try {
                mSign = jsonUser.getString("sign");
            } catch (JSONException e) {
                System.out.println(EroMsg + "sign");
            }

        } catch (Exception e) {
            System.out.println("JSON解析出错 User");
            e.printStackTrace();
        }
    }

}

  比如上面这个用户信息,在APP的很多界面都会用到,没有必要每次用到都做一次网络请求,所以直接用一个单例类做存储,用到直接调用。
  上面JSON解析的代码我也直接扔在单例类里,代码量不大,感觉没必要单独搞个类去做数据解析。上面我没用类似Gson这种框架去做解析,一是我们要解析的JSON数据量不太大,二嘛,好像后端给的JSON数据不是很合法啊,总是各种问题,折腾来折腾去,我发现如果自己手写早写好了,当然也可能我自己Gson用的不熟练导致的。。。
  上面看了下获取JSONArray类型的,其实JSONObject也差不多:

JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(
InterfaceConstant.SCHOOL_ACTIVITY_URL, null,
new Response.Listener<JSONObject>() {
    @Override
    public void onResponse(JSONObject jsonObject) {

    }
},
new Response.ErrorListener() {
    @Override
    public void onErrorResponse(VolleyError volleyError) {

    }
});
MyVolleySingleton.getInstance(this.getApplicationContext())
    .addToRequestQueue(jsonObjectRequest);

  下面再看下用Volley从服务器端获取图片的方法,下面是加载校园活动的ListView的Adapter的代码,其中用到了这部分知识:

package com.android.etuan.whereru.adapter;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;

import com.android.etuan.whereru.MyVolleySingleton;
import com.android.etuan.whereru.R;
import com.android.etuan.whereru.utils.jsonjavabean.mActivity;
import com.android.volley.toolbox.NetworkImageView;

import java.util.List;

public class CampusActivityListViewAdapter extends BaseAdapter {

    private Context mContext;
    private List<mActivity> mActivityDataList;
    private LayoutInflater mLayoutInflater;

    //把该做的工作放在构造函数里做掉去,以免在getView中反复操作
    public CampusActivityListViewAdapter(Context context) {
        mContext = context;
        mLayoutInflater = LayoutInflater.from(mContext);
    }


    public void setmActivityDataList(List<mActivity> mActivityDataList) {
        this.mActivityDataList = mActivityDataList;
    }

    @Override
    public int getCount() {
        return mActivityDataList.size();
    }

    @Override
    public Object getItem(int position) {
        return mActivityDataList.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    public static class ViewHolder {
        public TextView activityTitleTextView;
        public TextView activitySponsorTextView;
        public TextView activityCreateTimeTextView;
        public TextView activityKeywordTextView;

        public NetworkImageView activityPosterImageView;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        ViewHolder viewHolder = null;

        if (convertView == null) {

            convertView = mLayoutInflater
                    .inflate(R.layout.campus_activity_home_page_activity_listview_item_layout, null);

            viewHolder = new ViewHolder();

            viewHolder.activityTitleTextView = (TextView)
                    convertView.findViewById(R.id.activity_title);
            viewHolder.activitySponsorTextView = (TextView)
                    convertView.findViewById(R.id.activity_sponsor);
            viewHolder.activityCreateTimeTextView = (TextView)
                    convertView.findViewById(R.id.activity_create_time);
            viewHolder.activityKeywordTextView = (TextView)
                    convertView.findViewById(R.id.activity_keyword);

            viewHolder.activityPosterImageView = (NetworkImageView)
                    convertView.findViewById(R.id.activity_poster);

            //设置加载过程中的默认图片
            viewHolder.activityPosterImageView.setDefaultImageResId(R.drawable.loading_image);
            //设置加载出错时的图片
            viewHolder.activityPosterImageView.setErrorImageResId(R.drawable.loading_image_error);

            convertView.setTag(viewHolder);
        } else {
            viewHolder = (ViewHolder) convertView.getTag();
        }

        viewHolder.activityTitleTextView.setText(mActivityDataList.get(position).getTitle());
        viewHolder.activitySponsorTextView.setText(mActivityDataList.get(position).getAuthorName());
        viewHolder.activityCreateTimeTextView.setText(mActivityDataList.get(position).getCreated());
        viewHolder.activityKeywordTextView.setText(mActivityDataList.get(position).getKeyword());

        //这里使用Volley来进行图片的加载,图片放在NetworkImageView中
        viewHolder.activityPosterImageView.setImageUrl(
                mActivityDataList.get(position).getImgUrl(),
                MyVolleySingleton.getInstance(mContext.getApplicationContext()).getImageLoader());

        return convertView;

    }

}  

  其实核心的就一句代码:    

viewHolder.activityPosterImageView.setImageUrl(mActivityDataList.get(position).getImgUrl(),MyVolleySingleton.getInstance(mContext.getApplicationContext()).getImageLoader());

  当然前提是你单例类已经写好了,JSON也解析好了,这里注意用NetworkImageView这个控件取代ImageView来放图片。
  
  对了,最后给个post的例子,Google给的教程里好像没有post相关的例子。比如用户注册时就会用到post,代码如下(同样,删掉了部分相关度不高的代码):

Map<String, String> params = new HashMap<>();
params.put("name", userName);
params.put("password", password);
params.put("phone", phoneNumber);
params.put("sex", mSexChooseResult);
params.put("school", mSchoolName);

JSONObject jsonObject = new JSONObject(params);
JsonObjectRequest jsonRequest = new JsonObjectRequest(
        InterfaceConstant.REGISTER_URL, jsonObject,
        new Response.Listener<JSONObject>() {
            @Override
            public void onResponse(JSONObject jsonObject) {

            }
        },
        new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError volleyError) {

            }
        });
MyVolleySingleton.getInstance(RegisterPageTwoActivity.this.getApplicationContext())
        .addToRequestQueue(jsonRequest);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值