本片文章主要介绍利用Volley如何自定义一些常用的网络请求,比如附带cookie的get、post、下载网络图片等。具体有关Volley的介绍,请参考 时之沙的博文:Android 网络通信框架Volley简介(Google IO 2013)。
首先給大家看一下运行效果图:
项目源码在文章最后,欢迎下载!!~
Volley请求大致经过一下几个步骤:
- 初始化Volley的查询对象;
- 创建网络请求:返回值格式可以是JSONObject、JSONArray、String等;
- 将请求添加到Volley的查询对象中;
- 异步执行请求,得到结果。
一、初始化Volley查询对象RequestQueue
RequestQueue在项目中,只需要被初始化一次,即可实现在需要网络请求的时候调用。所以将其初始化工作,放在了Application层级。
/**
* Volley查询队列FIFO
*/
private static RequestQueue mRequestQueue;
/**
* @return Volley 查询队列
*/
public static RequestQueue getRequestQueue() {
// Cookie存到在mHttpClient中
if (mRequestQueue == null) {
mHttpClient = new DefaultHttpClient();
mRequestQueue = Volley.newRequestQueue(sInstance,
new HttpClientStack(mHttpClient));
}
return mRequestQueue;
}
二、创建网络请求
PS:项目只实现了返回值为json格式的请求,其他类型如jsonarray、string等,直接修改其请求参数即可。
Volley源码中,构造JSONObject请求代码如下:
JsonObjectRequest jsonReq = new JsonObjectRequest(url, jsonParams, success, error);
在该demo中,NetworkUtil.java负责定义请求的公用方法,并在每次请求之前,添加了网络判断。
public boolean isConnected() {
ConnectivityManager connectivityManager = (ConnectivityManager) mContext
.getSystemService(Context.CONNECTIVITY_SERVICE);
if (null != connectivityManager) {
NetworkInfo networkInfo[] = connectivityManager.getAllNetworkInfo();
if (null != networkInfo) {
for (NetworkInfo info : networkInfo) {
if (info.getState() == NetworkInfo.State.CONNECTED) {
Log.e(TAG, "the net is connected");
return true;
}
}
}
}
return false;
}
public void getJSONObjectForGet(String url, Listener<JSONObject> success,
ErrorListener error) {
try {
if (!isConnected()) {
Toast.makeText(mContext, "网络不可用,请检查网络连接!!~", Toast.LENGTH_LONG)
.show();
return;
}
JsonObjectRequest jsonReq = new JsonObjectRequest(url, null,
success, error);
addToRequestQueue(jsonReq, this.TAG);
} catch (Exception e) {
e.printStackTrace();
}
}
public void getJSONObjectForPost(String url,
HashMap<String, String> params, Listener<JSONObject> success,
ErrorListener error) {
try {
if (!isConnected()) {
Toast.makeText(mContext, "网络不可用,请检查网络连接!!~", Toast.LENGTH_LONG)
.show();
return;
}
JsonObjectRequest jsonReq = new JsonObjectRequest(url,
new JSONObject(params), success, error);
addToRequestQueue(jsonReq, this.TAG);
} catch (Exception e) {
e.printStackTrace();
}
}
三、将请求添加到Volley的查询对象中
在上述代码中,实现了将请求添加到Volley的查询对象中。
addToRequestQueue(jsonReq, this.TAG);
四、异步执行请求,并显示结果
若请求成功,则调用上述代码中传入的success对象,否则error对象被调用。在该demo中,将请求结果显示在textview中。
private void sendRequestForGet(String url) {
getmNetworkUtil(TAG).getJSONObjectForGet(url,
new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
result.setText(response.toString());
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
result.setText(error.getMessage());
}
});
}
五、实现下载网络图片
Volley封装的图片下载源码,存放在com.android.volley.ImageLoader.java中:
Request<?> newRequest =
new ImageRequest(requestUrl, new Listener<Bitmap>() {
@Override
public void onResponse(Bitmap response) {
onGetImageSuccess(cacheKey, response);
}
}, maxWidth, maxHeight,
Config.RGB_565, new ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
onGetImageError(cacheKey, error);
}
});
mRequestQueue.add(newRequest);
同样是先构建一个request,之后将请求添加到查询队列中。
以下一段代码,是我封装好的图片下载方法。
/**
* 下载网络图片
*
* @param mImageView 显示图片的image控件
* @param url 网络图片地址
* @param waitImage 下载等待图片
* @param errorImage 下载出错图片
* */
public void showImageByImageLoader(ImageView mImageView, String url,
int waitImage, int errorImage) {
try {
if (mImageView == null || url == null) {
return;
}
if (!isConnected()) {
Toast.makeText(mContext, "网络不可用,请检查网络连接!!~", Toast.LENGTH_LONG)
.show();
return;
}
ImageLoader mImageLoader = new ImageLoader(getmRequestQueue(),
new BitmapCache());
ImageListener listener = ImageLoader.getImageListener(mImageView,
waitImage, errorImage);
mImageLoader.get(url, listener);
} catch (Exception e) {
e.printStackTrace();
}
}
六、取消请求
在实际应用中,往往会出现这样的情形。比如页面中存在未加载完成的部分,但是用户已经跳转了页面,按照以往写法,Thread或者AsyncTask在页面离开之后,线程仍在继续,并没有因为页面的离开而停止。这样就会产生系统资源浪费,更严重的可能带来系统崩溃的问题。Volley中提供了停止请求的方法,可以在程序的适当生命周期的时候调用。
@Override
protected void onStop() {
super.onStop();
getmNetworkUtil(TAG).cancelRequest();
}
public void cancelRequest() {
cancelPendingRequests(this.TAG);
}
/**
* 根据tag停止request
*
* @param tag
*/
public void cancelPendingRequests(Object tag) {
if (mRequestQueue != null) {
mRequestQueue.cancelAll(tag);
}
}
写在最后:
由于本人写博客的经验不足,可能文章存在很多不足。欢迎朋友们指正错误,我的QQ:1065885952,谢谢!!~