一、Volley特點
通信更快,更簡單(數據量不大,但網絡通信頻繁)
Get、Post網絡請求及網絡圖像的高效率異步處理
排序(可以通過網絡請求的優先級進行處理)
網絡請求的緩存
多級別取消請求
和Activity生命周期的聯動
二、為什么使用Volley
高效的Get/Post方式的數據請求交互
網絡圖片加載和緩存
三、Volley框架的使用
1.Volley的GET、Post
首先我們需要知道Volley自帶了三種返回類型:
StringRequest:主要使用在對請求數據的返回類型不確定的情況下,StringRequest涵蓋了JsonObjectRequest和JsonArrayRequest。
JsonObjectRequest:當確定請求數據的返回類型為JsonObject時使用。
JsonArrayRequest:當確定請求數據的返回類型為JsonArray時使用。
首先我們需要建立一個全局的請求隊列,這樣我們可以將一個請求加入到這個全局隊列中,並可以管理整個APP的所有請求,包括取消一個或所有的請求。
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; } }
注意,我們需要在AndroidManifest中注冊這個Application,記得加上網絡權限
使用Get方法來請求數據
返回數據為StringRequest
private void volley_Get(){ String url = "https://tcc.taobao.com/cc/json/mobile_tel_segment.htm?tel=......"; 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("abcGet"); MyApplication.getHttpQueues().add(request); }
這里面需要注意的便是構造StringRequest實例時傳入的參數
第一個參數:請求數據的方法(Method.GET...)
第二個參數:請求數據的路徑
第三個參數:請求成功時的回調方法(可以在里面處理數據)
第四個參數:請求失敗時的回調方法
這下面還有一個方法
request.setTag();我們通過這個方法來為request設置標識,便於以后進行刪除,查找請求的操作。
返回數據為JsonObjectRequest時
private void volley_Get(){ String url = "https://tcc.taobao.com/cc/json/mobile_tel_segment.htm?tel=... "; 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("abcGet"); MyApplication.getHttpQueues().add(request); }
使用方法同上,但要注意的是,與之不同的是多了第三個參數,這里是用來放,傳參時Json格式數據的,如果用的是GET方法,傳入參數在url中,可以將其設置為null。
使用Post請求數據
返回數據為StringRequest
public void vollye_Post(){ String url = "https://tcc.taobao.com/cc/json/mobile_tel_segment.htm"; StringRequest request = new StringRequest(Request.Method.POST, 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(); } }){ @Override protected Map<String, String> getParams() throws AuthFailureError { Map<String,String> hashMap = new HashMap<>(); hashMap.put("tel", "...... "); return hashMap; } }; request.setTag("abcPost"); MyApplication.getHttpQueues().add(request); }
Post請求的方法使用與Get方法相似,但它多了一個方法
getParams()這個方法用Map來獲取你所需要Post的數據
返回數據為Json格式數據時
即將你所要傳入的數據放到參數中即可,不用使用getParams()方法
private void volleyPost() { String url = "http://www.kuaidi100.com/query"; Map<String,String> map = new HashMap<>(); map.put("type","yuantong"); map.put("postid","....."); //將map轉化為JSONObject對象 JSONObject jsonObject = new JSONObject(map); JsonObjectRequest request = new JsonObjectRequest(Method.POST, url, jsonObject, new Listener<JSONObject>() { @Override public void onResponse(JSONObject jsonObject) {//jsonObject為請求返回的Json格式數據 Toast.makeText(MainActivity.this,jsonObject.toString(),Toast.LENGTH_LONG).show(); } }, new ErrorListener() { @Override public void onErrorResponse(VolleyError volleyError) { Toast.makeText(MainActivity.this,volleyError.toString(),Toast.LENGTH_LONG).show(); } }); //設置請求的Tag標簽,可以在全局請求隊列中通過Tag標簽進行請求的查找 request.setTag("testPost"); //將請求加入全局隊列中 MyApplication.getHttpQueues().add(request); }
2.與Avctivity生命周期聯動
其實就是在Activity退出時候或銷毀時候,取消對應的網絡請求,避免網絡請求在后台浪費資源,所以,我們一般在onStop()方法中通過之前設置的Tag取消網絡請求:
@Override protected void onStop() { super.onStop(); //通過Tag標簽取消請求隊列中對應的全部請求 MyApplication.getHttpQueues().cancelAll(tag); }
3.Volley的二次封裝
public abstract class VolleyInterface { public Context mContext; public static Response.Listener mListener; public static Response.ErrorListener mErrorListener; public VolleyInterface(Context context, Response.Listener listener, Response.ErrorListener errorListener) { mContext = context; mListener = listener; mErrorListener = errorListener; } public abstract void onSuccess(String result);//成功的回調 public abstract void onError(VolleyError error);//失敗的回調 public Response.Listener successListener(){ mListener = new Response.Listener() { @Override public void onResponse(String response) { //我們可以在這里設置一些通用的方法,比如說比如一個顯示百分比的加載框等等 onSuccess(response); } }; return mListener; } public Response.ErrorListener errorListener(){ mErrorListener = new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { //提示請求失敗的對話框,避免重復書寫 onError(error); } }; return mErrorListener; } }
public class VolleyRequest { public static StringRequest stringRequest; public static Context sContext; public static void RequestGet(Context context,String url, String tag, VolleyInterface vif){ sContext = context; MyApplication.getHttpQueues().cancelAll(tag);//如果之前存在,先取消,避免重復的請求 stringRequest = new StringRequest(Request.Method.GET,url,vif.successListener(),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,VolleyInterface vif){ MyApplication.getHttpQueues().cancelAll(tag); stringRequest = new StringRequest(url,vif.successListener(),vif.errorListener()){ @Override protected Map<String, String> getParams() throws AuthFailureError { return params; } }; stringRequest.setTag(tag); MyApplication.getHttpQueues().add(stringRequest); //MyApplication.getHttpQueues().start(); //建議不要手動調用 RequestQueue 的 start() 方法,引起的問題“經常會報com.android.volley.NoConnectionError: java.io.InterruptedIOException”,然后就內容加載失敗。。。 因為在 Volley.newRequestQueue() 方法中,已經調用了 start() 方法。 } }
使用自己的封裝方法
private void volley_Get(){ String url = "https://tcc.taobao.com/cc/json/mobile_tel_segment.htm?tel=15850781443"; VolleyRequest.RequestGet(MainActivity.this, url, "abcGet", new VolleyAbstact(MainActivity.this,VolleyAbstact.mlistener,VolleyAbstact.mErrorListenerl) { @Override public void onMySuccess(String result) { Toast.makeText(MainActivity.this,result,Toast.LENGTH_SHORT).show(); } @Override public void onMyError(VolleyError error) { Toast.makeText(MainActivity.this,error.toString(),Toast.LENGTH_SHORT).show(); } }); }
4.獲取網絡圖片
加載圖片緩存
LruCache:這個類非常適合用來緩存圖片,它的主要算法原理是把最近使用的對象用強引用存儲在 LinkedHashMap 中,並且把最近最少使用的對象在緩存值達到預設定值之前從內存中移除。
ImageCache:Volley框架內部自己處理了DiskBasedCache硬盤緩存,但是沒有處理LruCache內存緩存,因為一般在處理圖片的問題上才更多的用到LruCache緩存,但是它提供了一個ImageCache接口供我們自己實現,該接口默認需要實現兩個方法:getBitmap(String key)和putBitmap(String key, Bitmap bitmap)
加載圖片與監聽 ImageRequest:
ImageLoader:
NetworkImageView:
1.使用ImageRequest加載網絡圖片
ImageRequest request = new ImageRequest(url, new Response.Listener<Bitmap>() { @Override public void onResponse(Bitmap bitmap) { imageView.setImageBitmap(bitmap); } }, 0, 0, Bitmap.Config.RGB_565, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError volleyError) { imageView.setBackgroundResource(Color.BLACK); } }); MyApplication.getHttpQueues().add(request);
第一個參數:請求數據的路徑
第二個參數:數據請求成功后的回調
第三、四個參數:允許的最大寬度、高度(0,0時指的是原圖傳入)
第五個參數:指定圖片的格式
第六個參數:數據請求失敗后的回調
2.使用ImageLoader加載圖片
ImageLoader也可以用於加載網絡上的圖片,並且它的內部也是使用ImageRequest來實現的,不過ImageLoader明顯要比ImageRequest更加高效,因為它不僅可以幫我們對圖片進行緩存,還可以過濾掉重復的鏈接,避免重復發送請求。
首先你需要建立一個緩存類
public class BitmapCache implements ImageLoader.ImageCache { public LruCache<String,Bitmap> cache; public int max = 10*1024*1024; 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); } }
然后在MainActivity中
ImageLoader loader = new ImageLoader(MyApplication.getHttpQueues(),new BitmapCache()); ImageLoader.ImageListener listener = ImageLoader.getImageListener(imageView,Color.BLACK,Color.BLACK); loader.get(url,listener);
getImageView中
第一個參數:放置圖片的控件
第二個參數:請求默認的圖片
第三個參數:請求失敗的圖片
3.使用networkImageView輔助加載圖片
實例化networkImageView后
String url = "https://www.baidu.com/img/bdlogo.png"; ImageLoader loader = new ImageLoader(MyApplication.getHttpQueues(),new BitmapCache()); networkImageView.setDefaultImageResId(Color.BLACK); networkImageView.setErrorImageResId(Color.BLUE); networkImageView.setImageUrl(url,loader);
第一個方法:請求默認的圖片
第二個方法:請求失敗的圖片
第三個方法:請求得到的圖片
四、總結:
到目前為止,本文就結束了,這篇文章主要講了對Volley的粗糙使用,並未涉及太過復雜的知識。
