我们平时开发Android app 不可避免的会使用到网络技术,大多数情况下我们都会以http或者https来请求网络数据,而传统的HttpURLConnection、HttpClient,使用起来稍显繁琐。一些网络开发框架也应运而生,今天所要讲的Volley就是其中的一种。个人比较倾向于这个网络框架,究其原因在于他的灵活性。你可以根据你app的架构,对volley进行相应的二次封装,使用起来相当的灵活方便。
在封装之前我们还是来简单了解一下volley, 先贴一个volley的下载地址,volley jar 下载地址
2013年Google I/O大会上推出了一个新的网络通信框架——Volley。Volley可是说是把AsyncHttpClient和Universal-Image-Loader的优点集于了一身,既可以像AsyncHttpClient一样非常简单地进行HTTP通信,也可以像Universal-Image-Loader一样轻松加载网络上的图片。除了简单易用之外,Volley在性能方面也进行了大幅度的调整,它的设计目标就是非常适合去进行数据量不大,但通信频繁的网络操作,而对于大数据量的网络操作,比如说下载文件等,Volley的表现就会非常糟糕。至于Volley的使用,比较简单,不会的同学可以在网上搜搜demo,分分钟就能上手。
鉴于目前大多数网络请求数据格式都是Json ,我们今天就以JsonRequest来讲解一下Volley的二次封装。
第一步:使用Volley之前需要初始化 这步操作建议在Application类中实现
VolleyQueueController.init(getApplicationContext());
第二步:创建访问数据的回调接口
public interface UIDataListener {
void onDataChanged(T data);
void onErrorHappend(String errorMsg);
}
第三步:请求对象的封装
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.List;
import java.util.Map;
import org.apache.http.NameValuePair;
import org.apache.http.client.utils.URLEncodedUtils;
import org.json.JSONObject;
import com.android.volley.DefaultRetryPolicy;
import com.android.volley.NetworkResponse;
import com.android.volley.ParseError;
import com.android.volley.Response;
import com.android.volley.Response.ErrorListener;
import com.android.volley.Response.Listener;
import com.android.volley.toolbox.HttpHeaderParser;
import com.android.volley.toolbox.JsonRequest;
/**
* @author Mr.Himan
*
*/
public class NetWorkRequest extends JsonRequest {
private static final int TIME_OUT = 10000;
public NetWorkRequest(int method, String url,
Map postParams, Listener listener,
ErrorListener errorListener) {
super(method, url, paramstoString(postParams), listener, errorListener);
setRetryPolicy(new DefaultRetryPolicy(TIME_OUT, 0,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
}
public NetWorkRequest(String url, List params,
Listener listener, ErrorListener errorListener) {
this(Method.GET, urlBuilder(url, params), null, listener, errorListener);
}
public NetWorkRequest(String url, Listener listener,
ErrorListener errorListener) {
this(Method.GET, url, null, listener, errorListener);
}
@Override
protected Response parseNetworkResponse(NetworkResponse response) {
try {
JSONObject jsonObject = new JSONObject(new String(response.data,
"UTF-8"));
return Response.success(jsonObject,
HttpHeaderParser.parseCacheHeaders(response));
} catch (Exception e) {
return Response.error(new ParseError(e));
}
}
// 拼接get 请求参数
private static String urlBuilder(String url, List params) {
return url + "?" + URLEncodedUtils.format(params, "UTF-8");
}
// 拼接Post请求参数
private static String paramstoString(Map params) {
if (params != null && params.size() > 0) {
String paramsEncoding = "UTF-8";
StringBuilder encodedParams = new StringBuilder();
try {
for (Map.Entry entry : params.entrySet()) {
encodedParams.append(URLEncoder.encode(entry.getKey(),
paramsEncoding));
encodedParams.append('=');
encodedParams.append(URLEncoder.encode(entry.getValue(),
paramsEncoding));
encodedParams.append('&');
}
return encodedParams.toString();
} catch (UnsupportedEncodingException uee) {
throw new RuntimeException("Encoding not supported: "
+ paramsEncoding, uee);
}
}
return "";
}
}
第四步:构建网络请求Helper
import java.util.List;
import java.util.Map;
import org.apache.http.NameValuePair;
import org.apache.http.client.utils.URLEncodedUtils;
import org.json.JSONObject;
import android.app.Activity;
import android.os.Handler;
import com.android.volley.Request.Method;
import com.android.volley.Response;
import com.android.volley.Response.ErrorListener;
import com.android.volley.VolleyError;
import com.css.volunteer.net.volley.NetWorkRequest;
import com.css.volunteer.net.volley.UIDataListener;
import com.css.volunteer.net.volley.VolleyQueueController;
import com.css.volunteer.utils.LoadingWindow;
import com.css.volunteer.utils.MToast;
import com.handmark.pulltorefresh.library.PullToRefreshListView;
/**
* Volley框架的二次封装
*
* @author Mr.Himan
*
*/
public abstract class NetWorkHelper implements
Response.Listener, ErrorListener {
private Activity mActivity;
private boolean isShowHint = true; // is show the hint message popupWindow
public NetWorkHelper(Activity activity) {
super();
this.mActivity = activity;
}
protected Activity mGetContext() {
return mActivity;
}
/**
* 是否开启加载数据请求的提示框
*/
public void closeShowHint() {
isShowHint = false;
}
protected NetWorkRequest getRequestForGet(String url,
List params) {
if (params == null) {
return new NetWorkRequest(url, this, this);
} else {
return new NetWorkRequest(url, params, this, this);
}
}
protected NetWorkRequest getRequestForPost(String url,
Map params) {
return new NetWorkRequest(Method.POST, url, params, this, this);
}
public void doHttpGet(String url, List params) {
if (isShowHint) {
// 弹出正在加载数据弹框
LoadingWindow.loadingWindow(mActivity, "Loading");
}
NetWorkRequest requestForGet = getRequestForGet(url, params);
requestForGet.setTag(urlBuilder(url, params));
VolleyQueueController.getInstance().cancelAll(urlBuilder(url, params));
VolleyQueueController.getInstance().add(requestForGet);
}
/**
* get请求
*
* @param url
*/
public void doHttpGet(String url) {
doHttpGet(url, null);
}
private static String urlBuilder(String url, List params) {
if (params == null) {
return url;
}
return url + "?" + URLEncodedUtils.format(params, "UTF-8");
}
/**
* post请求
*
* @param url
*/
public void doHttpPost(String url, Map params) {
VolleyQueueController.getInstance().add(getRequestForPost(url, params));
}
@Override
public void onErrorResponse(VolleyError error) {
if (isShowHint) {
LoadingWindow.closeWindow();
}
showErrorMsg();
disposeVolleyError(error);
}
protected abstract void disposeVolleyError(VolleyError error);
@Override
public void onResponse(JSONObject response) {
if (isShowHint) {
LoadingWindow.closeWindow();
}
if (response != null) {
disposeResponse(response);
} else {
showErrorMsg();
}
}
/**
* 数据加载错误提示
*/
protected void showErrorMsg() {
}
protected abstract void disposeResponse(JSONObject response);
private UIDataListener dataListener;
public void setDataListener(UIDataListener dataListener) {
this.dataListener = dataListener;
}
protected void notifyDataChanged(T data) {
if (dataListener != null) {
dataListener.onDataChanged(data);
}
}
protected void notifyErrorHappened() {
if (dataListener != null) {
dataListener.onErrorHappend();
}
}
}
到这里Volley的二次封装就完成了,看下使用
import org.json.JSONException;
import org.json.JSONObject;
import android.app.Activity;
import com.android.volley.VolleyError;
import com.css.volunteer.manager.DialogManager;
import com.css.volunteer.net.NetWorkHelper;
import com.css.volunteer.utils.MToast;
public abstract class UserNetHelper extends NetWorkHelper {
public UserNetHelper(Activity context) {
super(context);
}
@Override
protected void disposeVolleyError(VolleyError error) {
onErrorHappend(error);
}
@Override
protected void disposeResponse(JSONObject response) {
// 解析数据获取bean
String userName = response.getString("userName");
String userSex = response.getString("userSex");
User user = new User(userName,userSex);
notifyDataChanged(user);
}
@Override
protected void showErrorMsg() {
// 统一错误提示信息处理
}
}
public LoginActivity extends Activity{
...代码省略...
public void getUserInfo(){
UserNetHelper userNetHelper =new UserNetHelper(this);
userNetHelper.setDataListener(new UIDataListener() {
@Override
public void onDataChanged(User data) {
// 获取user
}
@Override
public void onErrorHappend(User data) {
// 获取数据失败
}