1.1 Volley 的特点
1 使网络通信更快,更简单,更健壮;
2 Get/Post网络请求及网络图像的高效率异步请求;
3 可以对网络请求的优先级进行排序处理;
4 可以进行网络请求的缓存;
5 可以取消多级别请求;
6 可以和Activity生命周期联动
1.2 为什么要使用Volley?
功能上:
高效的Get/Post方式的数据请求交互;
网络图片的加载和缓存过程简单化。
其他:
谷歌官方推出的,比较权威(谷歌针对Android的网络平台通讯库)
对网络请求优化的非常好,非常权威性能很稳定、强劲
2. Volley 的使用
2.1 首先建立 Volley 的全局请求队列
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;
}
}
//记得注册并加上网络权限
2.2 StringRequest,创建 volley_Get() 方法
private void volley_Get() {
String url = "http://192.168.1.46:8080/zhbj/categories.json";
StringRequest request = new StringRequest(Request.Method.GET, url, new Response.Listener<String>() {
@Override
public void onResponse(String s) {
//数据请求成功
Toast.makeText(MainActivity.this, s, Toast.LENGTH_SHORT).show();
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError volleyError) {
//请求失败的情况
Toast.makeText(MainActivity.this, volleyError.toString(), Toast.LENGTH_SHORT).show();
}
});
request.setTag("volley_string_get");//与Activity联动的关键
MyApplication.getHttpQueues().add(request);//名字得有意义
}
2.3 jsonObjectRequest,创建 volley_Get2() 方法
因为这里是Get请求方式,第三个参数设置为null,post方式时传入附带参数的JsonObject
private void volley_Get2() {
String url = "http://192.168.1.46:8080/zhbj/categories.json";
JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET, url, null, new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject jsonObject) {
Toast.makeText(MainActivity.this, jsonObject.toString(), Toast.LENGTH_SHORT).show();
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError volleyError) {
Toast.makeText(MainActivity.this, volleyError.toString(), Toast.LENGTH_SHORT).show();
}
});
request.setTag("volley_jsonobject_get");
MyApplication.getHttpQueues().add(request);
}
2.4 StringRequest,创建 volley_post() 方法
注意 getParams() 这个传递数据的方法
public void bt_string_post(View view){
String url = "http://192.168.1.46:8080/zhbj/categories.json";
StringRequest request = new StringRequest(Request.Method.POST,
url, new Response.Listener<String>() {
@Override
public void onResponse(String s) {
Toast.makeText(MainActivity.this, "请求成功", Toast.LENGTH_SHORT).show();
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError volleyError) {
Toast.makeText(MainActivity.this, "请求失败", Toast.LENGTH_SHORT).show();
}
}){
@Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String,String> hashMap = new HashMap<>();
hashMap.put("phone","110");
hashMap.put("key","lizi");
return hashMap;
}
};
request.setTag("volley_string_post");
MyApplication.getHttpQueues().add(request);
}
2.5 jsonObjectRequest 的 post 请求方式
public void bt_jsonobject_post(View view){
String url = "http://192.168.1.46:8080/zhbj/categories.json";
Map<String,String> hashMap = new HashMap<>();
hashMap.put("phone","110");
hashMap.put("key","lizi");
JSONObject object = new JSONObject(hashMap);
JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET, url, object, new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject jsonObject) {
Toast.makeText(MainActivity.this, "请求成功", Toast.LENGTH_SHORT).show();
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError volleyError) {
Toast.makeText(MainActivity.this, "接口不支持post,注定失败,用法正确", Toast.LENGTH_SHORT).show();
}
});
}
3. 与 Activity 生命周期的关联
@Override
protected void onStop() {
super.onStop();
MyApplication.getHttpQueues().cancelAll("volley_string_get");
}
4. Volley 的简单二次回调封装,方便全局控制,只需在ValleyInterface 中实现逻辑即可
4.1 这个类是请求成功与失败接口的回调,封装成功与失败两种抽象类
public abstract class ValleyInterface {
public Context mContext;
public static Response.Listener mListener;
public static Response.ErrorListener mErrorListener;
public ValleyInterface(Context context, Response.Listener<String> listener,
Response.ErrorListener errorListener) {
// 进行事件的绑定
this.mContext = context;
this.mErrorListener = errorListener;
this.mListener = listener;
}
public abstract void onMySucess(String result);
public abstract void onMyError(VolleyError volleyError);
//实例化两种请求方法,两个回调示例
public Response.Listener<String> loadingListener(){
mListener = new Response.Listener<String>() {
@Override
public void onResponse(String arg0) {
onMySucess(arg0);
}
};
return mListener;
}
// 失败的回调方式
public Response.ErrorListener errorListener(){
mErrorListener = new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError volleyError) {
onMyError(volleyError);
}
};
return mErrorListener;
}
}
4.2 二次封装的类
public class ValleyRequest {
public static StringRequest stringRequest;
public static Context context;
public static void RequestGet(Context context,String url,String tag,ValleyInterface vif){
//最后一个是请求成功与失败接口的回调,这个接口涵盖成功与失败的回调,建立一个抽象类,封装这两个关键的方法
MyApplication.getHttpQueues().cancelAll(tag);//防止重复请求,消耗内存
stringRequest = new StringRequest(Request.Method.GET,url, vif.loadingListener(),vif.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 , ValleyInterface vif){
MyApplication.getHttpQueues().cancelAll(tag);
stringRequest = new StringRequest(url,vif.loadingListener(), vif.errorListener()){
@Override
protected Map<String, String> getParams() throws AuthFailureError {
return params;
}
};
stringRequest.setTag(tag);
MyApplication.getHttpQueues().add(stringRequest);
MyApplication.getHttpQueues().start();
}
}
4.3 二次 回调之后的Get请求用法
private void bt2_get() {
String url = "http://192.168.1.65:8080/zhbj/categories.json";
ValleyRequest.RequestGet(this, url, "abcGet", new ValleyInterface(this,
ValleyInterface.mListener,ValleyInterface.mErrorListener) {
@Override
public void onMySucess(String result) {
Toast.makeText(MainActivity.this, result, Toast.LENGTH_SHORT).show();
}
@Override
public void onMyError(VolleyError volleyError) {
Toast.makeText(MainActivity.this, volleyError.toString(), Toast.LENGTH_SHORT).show();
}
});
}
5. Volley 加载图片
- 缓存功能及简单介绍
- LruCache
- ImageCache
- 加载网络图片和监听
- ImageRequest
- ImageLoader
- NetworkImageView
public void loadImageByVolley(View v) { String url = "http://www.baidu.com/img/bdlogo.png"; // 第二个参数是图片请求成功的回调,两个数字是图片宽高最大(会做压缩处理),全为零表示加载原图, ImageRequest request = new ImageRequest(url, new Response.Listener<Bitmap>() { @Override public void onResponse(Bitmap bitmap) { iv_img.setImageBitmap(bitmap); } }, 0,0, Bitmap.Config.RGB_565, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError volleyError) { iv_img.setImageResource(R.mipmap.ic_launcher); } }); request.setTag("load_image_volley"); MyApplication.getHttpQueues().add(request); }
6.终极版 Volley 带缓存加载图片
imageCache 单独使用起不到缓存效果,结合LruCache
public class BitmapCache implements ImageLoader.ImageCache {
public LruCache<String,Bitmap> cache;
public int max = 10*1024*1024; //最大为 10M 的缓存
public BitmapCache(){
cache = new LruCache<String,Bitmap>(max){
@Override
protected int sizeOf(String key, Bitmap value) {
return value.getRowBytes()*value.getHeight();
}
};
}
@Override
public Bitmap getBitmap(String s) {
return cache.get(s);
}
@Override
public void putBitmap(String s, Bitmap bitmap) {
cache.put(s,bitmap);
}
}
两种带缓存加载图片的Volley方法
public void loadImageByVolley3(View view){
ImageLoader imageLoader = new ImageLoader(MyApplication.getHttpQueues(),new BitmapCache());
ImageLoader.ImageListener listener = ImageLoader.getImageListener
(iv_img,R.mipmap.ic_launcher,R.mipmap.ic_launcher);
//加载及缓存网络图片
imageLoader.get(url,listener);
}
使用NetworkImageView的方法
<com.android.volley.toolbox.NetworkImageView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:id="@+id/iv_img2"/>
networkImageView = (NetworkImageView)findViewById(R.id.iv_img2);
public void NetworkImageView(View view){
ImageLoader imageLoader = new ImageLoader(MyApplication.getHttpQueues(),new BitmapCache());
networkImageView.setDefaultImageResId(R.mipmap.ic_launcher);
networkImageView.setErrorImageResId(R.mipmap.ic_launcher);
networkImageView.setImageUrl(url,imageLoader);
}