(来源于慕课网JVR老师的讲课内容,本人整理总结)
还有网友的不错的总结,我写这篇文章只是出于梳理思路的目的。网友博客地址如下:
http://www.cnblogs.com/caobotao/p/5071658.html
Volley是网络通信库,适用于一些数据量不大,但需要频繁通信的网络操作。使用Volley进行网络开发可以提高开发效率和性能的稳定性。但是Volley不适用于文件的上传下载操作。
使用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.jar下载下来,放入libs目录下(eclipse)
/**
* 创建一个全局的请求队列
* @author Administrator
*
*/
public class MyApplication extends Application {
public static RequestQueue queues;
@Override
public void onCreate() {
super.onCreate();
queues = Volley.newRequestQueue(getApplicationContext());
}
public static RequestQueue getHttpQueues() {
return queues;
}
}
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.volleydemo"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="14"
android:targetSdkVersion="22" />
<!-- 添加网络操作权限 -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- 注册自定义的Application:android:name=".MyApplication" -->
<application
android:name=".MyApplication"
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
1、使用Get方式返回StringRequest对象:
(注意包要导对)
public class MainActivity extends Activity {
private TextView mTextView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTextView = (TextView) findViewById(R.id.tv_text);
volleyGetStringRequest();
}
/**
* 使用GET方式请求StringRequest数据
*/
private void volleyGetStringRequest() {
// 可以百度聚合数据,里面有很多实用的工具。在个人中心申请数据就可以得到相应的KEY
String url = "http://apis.juhe.cn/mobile/get?phone=你的11位手机号码&key=你申请的KEY";
StringRequest request = new StringRequest(Method.GET, url, new Listener<String>() {
@Override
public void onResponse(String response) {
Toast.makeText(MainActivity.this, response, Toast.LENGTH_LONG).show();
mTextView.setText(response);
}
}, new ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(MainActivity.this, error.toString(), Toast.LENGTH_LONG).show();
mTextView.setText("请求失败!");
}
});
// 设置请求的Tag标签,可以在全局请求队列中通过Tag标签进行请求的查找
request.setTag("testGet");
// 将请求加入全局队列中
MyApplication.getHttpQueues().add(request);
}
}
2、使用Get方式返回JsonObjectRequest对象:
/**
* 使用GET方式请求JsonObjectRequest数据
*/
private void volleyGetJsonObjectRequest() {
String url = "http://apis.juhe.cn/mobile/get?phone=你的11位手机号码&key=你申请的KEY";
JsonObjectRequest objectRequest = new JsonObjectRequest(Method.GET, url, null, new Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
Toast.makeText(MainActivity.this, response.toString(), Toast.LENGTH_LONG).show();
}
}, new ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(MainActivity.this, error.toString(), Toast.LENGTH_LONG).show();
}
});
objectRequest.setTag("testGet");
MyApplication.getHttpQueues().add(objectRequest);
}
3、使用Get方式返回JsonArrayRequest对象:
/**
* 使用GET方式请求JsonArrayRequest数据
*/
private void volleyGetJsonArrayRequest() {
String url = "http://apis.juhe.cn/mobile/get?phone=你的11位手机号码&key=你申请的KEY";
JsonArrayRequest arrayRequest = new JsonArrayRequest(url, new Listener<JSONArray>() {
@Override
public void onResponse(JSONArray response) {
Toast.makeText(MainActivity.this, response.toString(), Toast.LENGTH_LONG).show();
}
}, new ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(MainActivity.this, error.toString(), Toast.LENGTH_LONG).show();
}
});
arrayRequest.setTag("testGet");
MyApplication.getHttpQueues().add(arrayRequest);
}
4、使用Post方式返回StringRequest对象:
/**
* 使用POST方式请求StringRequest数据
*/
private void volleyPostStringRequest() {
// 查询邮编
String url = "http://v.juhe.cn/postcode/query?";
StringRequest request = new StringRequest(Method.POST, url, new Listener<String>() {
@Override
public void onResponse(String response) {
Toast.makeText(MainActivity.this, response.toString(), Toast.LENGTH_LONG).show();
}
}, new ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(MainActivity.this, error.toString(), Toast.LENGTH_LONG).show();
}
})
// 用户使用getParams()方法:用户在Volley中使用Post方式请求数据中参数的传递
{
@Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String> hashMap = new HashMap<>();
// 将请求参数名与参数值放入map中
hashMap.put("postcode", "邮编号");
hashMap.put("key", "你的KEY");
return hashMap;
}
};
request.setTag("testPost");
MyApplication.getHttpQueues().add(request);
}
5、使用Post方式返回StringRequest对象:
/**
* 使用POST方式请求JsonJsonObject数据
*/
private void volleyPostJsonJsonObject() {
String url = "http://v.juhe.cn/postcode/query?";
HashMap<String, String> hashMap = new HashMap<>();
// 将请求参数名与参数值放入map中
hashMap.put("postcode", "719000");
hashMap.put("key", "你的KEY");
JSONObject jsonObject = new JSONObject(hashMap);
JsonObjectRequest objectRequest = new JsonObjectRequest(Method.POST, url, jsonObject,
new Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
Toast.makeText(MainActivity.this, response.toString(), Toast.LENGTH_LONG).show();
}
}, new ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(MainActivity.this, error.toString(), Toast.LENGTH_LONG).show();
}
});
objectRequest.setTag("testPost");
MyApplication.getHttpQueues().add(objectRequest);
}
6、使用Post方式返回JsonArrayRequest对象:
与5所讲述的是类似的,参考Get。
与Activity生命周期的联动
可以在Activity关闭时取消请求队列中的请求:
@Override
protected void onStop() {
super.onStop();
// 通过Tag标签取消请求队列中对应的全部请求
MyApplication.getHttpQueues().cancelAll("testGet");
}
自定义Volley(简单的二次回调封装):
优点:全局使用一个方式,可控、可自定义定制需求。方便、灵活。
/**
* Volley请求成功和失败接口
*
* @author Administrator
*
*/
public abstract class VolleyInterface {
public Context mContext;
public static Listener<String> mListener;
public static ErrorListener mErrorListener;
public VolleyInterface(Context context, Listener<String> listener, ErrorListener errorListener) {
this.mContext = context;
VolleyInterface.mListener = listener;
VolleyInterface.mErrorListener = errorListener;
}
public abstract void onMySuccess(String response);
public abstract void onMyError(VolleyError error);
public Listener<String> loadingListener() {
mListener = new Listener<String>() {
@Override
public void onResponse(String response) {
onMySuccess(response);
// 提示弹出加载(全局)
}
};
return mListener;
}
public ErrorListener errorListener() {
mErrorListener = new ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
onMyError(error);
// 提示请求失败(全局)
}
};
return mErrorListener;
}
}
/**
* 自定义get和post请求
*
* @author Administrator
*
*/
public class VolleyRequest {
public static StringRequest stringRequest;
public static Context mContext;
/**
* get方式请求StringRequest对象
*
* @param context
* 上下文
* @param url
* 数据地址
* @param tag
* 标签
* @param volleyInterface
* 成功和失败接口
*/
public static void RequestGet(Context context, String url, String tag, VolleyInterface volleyInterface) {
MyApplication.getHttpQueues().cancelAll(tag);
StringRequest stringRequest = new StringRequest(Method.GET, url, volleyInterface.loadingListener(),
volleyInterface.errorListener());
stringRequest.setTag(tag);
MyApplication.getHttpQueues().add(stringRequest);
MyApplication.getHttpQueues().start();
}
public static void RequestPost(Context context, String url, String tag, final Map<String, String> params,
VolleyInterface volleyInterface) {
MyApplication.getHttpQueues().cancelAll(tag);
StringRequest stringRequest = new StringRequest(url, volleyInterface.loadingListener(),
volleyInterface.errorListener()) {
@Override
protected Map<String, String> getParams() throws AuthFailureError {
// TODO Auto-generated method stub
return params;
}
};
stringRequest.setTag(tag);
MyApplication.getHttpQueues().add(stringRequest);
MyApplication.getHttpQueues().start();
}
}
测试自定义MyVolley:
public class MyVolley extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
volleyGet();
}
private void volleyGet() {
String url = "url地址";
VolleyRequest.RequestGet(this, url, "testTag",
new VolleyInterface(this, VolleyInterface.mListener, VolleyInterface.mErrorListener) {
@Override
public void onMySuccess(String response) {
Toast.makeText(MyVolley.this, response.toString(), Toast.LENGTH_LONG).show();
}
@Override
public void onMyError(VolleyError error) {
Toast.makeText(MyVolley.this, error.toString(), Toast.LENGTH_LONG).show();
}
});
}
}
成功运行。
使用ImageRequest获取网络图片:
/**
* 使用ImageRequest获取网络图片
* @author Administrator
*
*/
public class MainActivity extends Activity {
private ImageView mImageView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
mImageView = (ImageView) findViewById(R.id.img_web);
String url = "http://img5q.duitang.com/uploads/item/201410/02/20141002194946_43Nda.jpeg";
ImageRequest imageRequest = new ImageRequest(url, new Listener<Bitmap>() {
@Override
public void onResponse(Bitmap response) {
mImageView.setImageBitmap(response);
}
}, 0, 0, Config.RGB_565, new ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
mImageView.setBackgroundResource(R.drawable.ic_launcher);
}
});
MyApplication.getHttpQueues().add(imageRequest);
}
}
使用ImageLoader缓存图片:
public class BitmapCache implements ImageCache {
public LruCache<String, Bitmap> lruCache;
// LruCache缓存对象的最大内存大小(10M)
public int maxSize = 10 * 1024 * 1024;
public BitmapCache() {
lruCache = new LruCache<String, Bitmap>(maxSize) {
@Override
protected int sizeOf(String key, Bitmap value) {
return value.getRowBytes()*value.getHeight();
}
};
}
@Override
public Bitmap getBitmap(String url) {
return lruCache.get(url);
}
@Override
public void putBitmap(String url, Bitmap bitmap) {
lruCache.put(url, bitmap);
}
}
public class ImageLoaderActivity extends Activity {
private ImageView mImageView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
mImageView = (ImageView) findViewById(R.id.img_web);
String url = "http://img5q.duitang.com/uploads/item/201410/02/20141002194946_43Nda.jpeg";
// imageCache单独使用没有效果
ImageLoader imageLoader = new ImageLoader(
MyApplication.getHttpQueues(),
new BitmapCache());
ImageListener imageListener = ImageLoader.getImageListener(
mImageView,
R.drawable.ic_launcher,
R.drawable.ic_launcher);
imageLoader.get(url, imageListener);
}
}
使用Volley自带的NetworkImageView(简洁方便):
<com.android.volley.toolbox.NetworkImageView
android:id="@+id/com_network"
android:layout_width="120dp"
android:layout_height="120dp"
android:layout_centerHorizontal="true"
android:layout_marginTop="30dp" />
/**
* 使用NetworkImageView加载图片
* @author Administrator
*
*/
public class NetworkImageActivity extends Activity {
private NetworkImageView mNetImageView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
mNetImageView = (NetworkImageView) findViewById(R.id.com_network);
String url = "http://img5q.duitang.com/uploads/item/201410/02/20141002194946_43Nda.jpeg";
ImageLoader imageLoader = new ImageLoader(
MyApplication.getHttpQueues(),
new BitmapCache());
// 只需设置默认图片、加载失败图片和图片地址
mNetImageView.setDefaultImageResId(R.drawable.ic_launcher);
mNetImageView.setErrorImageResId(R.drawable.load_fail);
mNetImageView.setImageUrl(url, imageLoader);
}
}
总体上Volley的用处分为这两个:
1、高效的Get/Post方式的数据请求交互;
2、网络图片的加载和缓存过程简单化。