Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> Android開發 >> 關於android開發 >> Volley的基本使用,Volley使用

Volley的基本使用,Volley使用

編輯:關於android開發

Volley的基本使用,Volley使用


本人初學,如有纰缪,望指正~     Volley是Google在2003年的I/O大會上推出的通信框架,結合了AsyncHttpClient和Universal-Image-Loader的優點——簡化了http的使用 + 異步加載圖片的神奇能力。Android中的Http實現主要有HttpUrlConnection和HttpClient兩種,關於二者的選擇Google在Blog中表示推薦在姜餅小人(API level = 9)及以上的版本中使用Java的HttpUrlConnection而在之前的版本使用Apache的HttpClient,這在Volley這個框架中也有明確的體現。   獲取Volley
git clone https://android.googlesource.com/platform/frameworks/volley
把它編譯成jar文件就可以加入libs了   一、簡單的請求(以StringRequest為例)   Http的通信最主要的部分應該就是發出請求和接收響應了,所以Volley的比較核心的一個類就是RequestQueue,一個請求隊列。它負責管理工作線程,讀寫緩存,和解析、分發響應(具體操作還是由具體的類實現),即將發出的Http請求都會首先聚集在這裡等待工作線程來實現請求。RequestQueue可以被看成一艘載滿Http請求的航空母艦,而工作線程就是彈射器喽。   所以按照航母起飛飛機的步驟,我們可以猜到利用Volley進行Http通信的簡單步驟:     1.獲取RequestQueue(得到一艘航母,可以是自己造的,也可以是委托別人造的,下面會提到)     2.實例化一個Request(得到一架飛機,你也知道飛機又很多類型啦)     3.將Request加入RequestQueue,等待工作線程將其發送出去(把飛機從機庫升上起飛甲板,等待彈射器把它扔出去)   起飛偵察機-發出GET請求   按照上面的步驟,第一步就是建立一個請求隊列,最簡單的方法就是用Volley.newRequestQueue(),這是一個特別方便的靜態方法,替我們默認實現了所有需要的東西(網絡、緩存等,這些在Volley中都有默認實現),它會返回一個已經開始運行的RequestQueue(相當於別人幫忙造了艘航母)。之後我們需要的只是設置好請求的響應監聽接口,把請求加入到這個隊列中就可以等著響應數據來敲門了。下面是Google文檔中的示例代碼: 復制代碼
 1   //初始化一個請求隊列
 2   RequestQueue queue = Volley.newRequestQueue(this);
 3   String url ="http://www.google.com";
 4   
 5   //根據給定的URL新建一個請求
 6   StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
 7               new Response.Listener() {
 8       @Override
 9       public void onResponse(String response) {
10          //在這裡操作UI組件是安全的,因為響應返回時這個函數會被post到UI線程來執行
11          // 在這裡盡情蹂躏響應的String。
12      }
13  }, new Response.ErrorListener() {
14      @Override
15      public void onErrorResponse(VolleyError error) {
16          // 出錯了怎麼辦?涼拌!並且在這裡拌。
17      }
18 });
19 // 把這個請求加入請求隊列
20 queue.add(stringRequest);
復制代碼 StringRequest是Request的具體實現之一,代表解析後的響應數據是一個字符串,相似的還有JsonRequest(包括JsonObjectRequest和JsonArrayRequest兩個可以使用的子類)、ImageRequest來滿足基本的使用,用法大同小異。主要是構造參數不一樣,分別如下:   1.public StringRequest(int method, String url, Listener<String> listener,ErrorListener errorListener);      參數說明:從左到右分別是請求方法(都封裝在Request中的Method接口內),請求URL,響應監聽接口實例,錯誤監聽接口實例。
  2.public JsonObjectRequest(int method, String url, JSONObject jsonRequest,Listener<JSONObject> listener, ErrorListener errorListener);      public JsonObjectRequest(String url, JSONObject jsonRequest, Listener<JSONObject> listener,ErrorListener errorListener);      參數說明:如果是GET請求的話,jsonRequest傳入null就可以了,否則在未指明請求方法的情況下(也就是第二個構造函數)會默認為POST請求。其他同上。   3.public JsonArrayRequest(String url, Listener<JSONArray> listener, ErrorListener errorListener);      參數說明:同上。   4.public ImageRequest(String url, Response.Listener<Bitmap> listener, int maxWidth, int maxHeight,Config decodeConfig, Response.ErrorListener errorListener);      參數說明:decodeConfig是圖片的顏色屬性,下面的幾個值都可以使用。   Bitmap.Config中的顏色屬性(枚舉類型) ALPHA_8   ARGB_4444 由於質量低,已經被棄用,推薦用ARGB_8888 ARGB_8888 每個像素用4byte存儲 RGB_565 每個像素用2byte存儲,紅色占5位,綠色占6位,藍色占5位   起飛戰斗機-發出POST請求   基本方式和上面一樣,但是怎麼裝導彈,啊不,是怎麼提交的數據呢? Volley會在Request的請求方法是POST(還有PUT和PATCH)的情況下調用Request類(就是XXXRequest的父類)的getParam()函數來獲取參數,提前劇透,如果使用的是HttpUrlConnection的話,調用getParam()是在HurlStatck中的addBodyIfExists()函數實現的,感興趣的話可以去看一下哈。所以,POST請求像下面這樣就可以了。 復制代碼
 1 //初始化一個請求隊列
 2 RequestQueue queue = Volley.newRequestQueue(this);
 3 String url ="http://www.google.com";
 4 
 5 //根據給定的URL新建一個請求
 6 StringRequest stringRequest = new StringRequest(Request.Method.POST, url,
 7    new Response.Listener() {
 8     @Override
 9     public void onResponse(String response) {
10         // 在這裡處理請求得到的String類型的響應
11    }
12 }, new Response.ErrorListener() {
13     @Override
14     public void onErrorResponse(VolleyError error) {
15         // 在這裡進行出錯之後的處理
16    }
17 }) {
18 @Override
19 protected Map<String, String> getParams() throws AuthFailureError {
20 
21 Map<String, String> map = new HashMap<String, String>(); 
22         map.put("params1", "value1"); 
23         map.put("params2", "value2"); 
24         return map
25  };
26 // 把這個請求加入請求隊列
27 queue.add(stringRequest);
復制代碼   後悔藥-取消請求   Request中有一個cancel()方法,調用這個就可以取消當前請求了,但是取消到哪一個層次就不一定了,但是Volley可以保證響應處理函數(就是onResponse()和onErroeResponse())不會被調用。還有一個一起取消多個請求,就是在發出請求前調用Request的setTag()方法為每個請求加一個標簽,這個方法的參數是Object,所以我們可以使用任何類型作為標簽。這樣就可以調用ReqiestQueue的cancelAll()函數取消一群標簽了。比較常用的方法就是,將發出這個請求的Activity或者Fragment作為標簽,並在onStop()中調用cancelAll()。   二、使用ImageLoader加載圖片   ImageLoader是一個可以實現圖片異步加載的類,但已經不是繼承與Request了。ImageLoader雖然是頭神獸,但必須在主線程召喚它,否則會拋出錯誤IllegalStateException,可能是因為ImageLoader在圖片返回時要直接操作ImageView,在主線程裡操作UI組件才是安全的,so~   用ImageLoader加載圖片分三步     1.創建ImageLoader     2.獲取一個ImageListener對象     3.調用ImageLoader的get()方法獲取圖片   ImageLoader的構造函數長成這樣:public ImageLoader(RequestQueue queue, ImageCache imageCache); 所以實例化一個ImageLoader需要一個RequestQueue(之前建立的就行),還有一個ImageCache,這是一個ImageLoader內部定義的接口,用來實現L1緩存——內存緩存(Volley在RequestQueue中已經實現了L2緩存——文件緩存)。ImageLoader中並沒有對傳入的ImageCache在使用前判空的代碼,傳null進去會出錯的。如果實在不想弄內存緩存,實現一個什麼都不做的ImageCache就好了。下面是代碼: 復制代碼
 1 ImageLoader imageLoader = new ImageLoader(mRequestQueue, new ImageCache() {  
 2     @Override  
 3     public void putBitmap(String url, Bitmap bitmap) {  
 4     }  
 5   
 6     @Override  
 7     public Bitmap getBitmap(String url) {  
 8         return null;  
 9     }  
10 });
11 
12 //default_image是正在加載圖片時占位用的
13 //error_image是加載不成功時顯示的圖片
14 ImageListener listener = ImageLoader.getImageListener(imageView, R.drawable.default_image, R.drawable.error_image); 
15imageLoader.get("your image url", listener); 
復制代碼   除了ImageLoader之外Volley中還有一個Image加載的神器——NetworkImageView,使用步驟如下:     1.在布局文件中加入控件,並在Java代碼中獲取實例     2.設置default_image,error_image,圖片URL,一個ImageLoader對象   代碼如下:
1 networkImageView = (NetworkImageView) findViewById(R.id.network_image_view); 
2 networkImageView.setDefaultImageResId(R.drawable.default_image);  
3 networkImageView.setErrorImageResId(R.drawable.error_image);
4 networkImageView.setImageUrl("your image url", imageLoader);  

 

三、Google推薦的用法   上面就是Volley的基本用法了,但是如果一個App需要頻繁的網絡通信的話,建立多個RequestQueue是件很奇怪的事兒(誰會因為臨時有飛機要在海上起飛就去新建一艘航母呢,這得多有錢啊),所以Google推薦我們只實例化一個RequestQueue來應付頻繁的Http通信,當然,要保證隊列的壽命和App一樣長。如何實現呢?Google又說了,不推薦在App的Application.onCretae()方法中實例化一個RequestQueue(不過確實是個簡單的方法哈),最好是建立一個單例模式的類,並把所有我們需要用到的Volley的瓶瓶罐罐都放進去,這樣顯得更模塊化。下面就是示例代碼。這段代碼中最重要的就是RequestQueue要用Application的Context實例化,要不然就會隨著Activity的生命周期不停重建。其實,像AsyncHttpClient中的純靜態使用方法也不錯(詳情見:http://loopj.com/android-async-http/) PS:下面還實現了一個簡單的ImageCache 復制代碼
 1 private static MySingleton mInstance;
 2     private RequestQueue mRequestQueue;
 3     private ImageLoader mImageLoader;
 4     private static Context mCtx;
 5 
 6     private MySingleton(Context context) {
 7         mCtx = context;
 8         mRequestQueue = getRequestQueue();
 9 
10         mImageLoader = new ImageLoader(mRequestQueue,
11                 new ImageLoader.ImageCache() {
12             private final LruCache<String, Bitmap>
13                     cache = new LruCache<String, Bitmap>(20);
14 
15             @Override
16             public Bitmap getBitmap(String url) {
17                 return cache.get(url);
18             }
19 
20             @Override
21             public void putBitmap(String url, Bitmap bitmap) {
22                 cache.put(url, bitmap);
23             }
24         });
25     }
26 
27     public static synchronized MySingleton getInstance(Context context) {
28         if (mInstance == null) {
29             mInstance = new MySingleton(context);
30         }
31         return mInstance;
32     }
33 
34     public RequestQueue getRequestQueue() {
35         if (mRequestQueue == null) {
36             // getApplicationContext()是關鍵, 它會避免
37             // Activity或者BroadcastReceiver帶來的缺點.
38             mRequestQueue = Volley.newRequestQueue(mCtx.getApplicationContext());
39         }
40         return mRequestQueue;
41     }
42 
43     public <T> void addToRequestQueue(Request<T> req) {
44         getRequestQueue().add(req);
45     }
46 
47     public ImageLoader getImageLoader() {
48         return mImageLoader;
49     }
50 }
復制代碼

 

四、Volley是怎麼管理請求的呢?   RequestQueue會維護一個緩存調度線程(cache線程)和一個網絡調度線程池(net線程)(注意,這是一池子線程),當一個Request被加到隊列中的時候,cache線程會把這個請求進行篩選:如果這個請求的內容可以在緩存中找到,cache線程會親自解析相應內容,並分發到主線程(UI)。如果緩存中沒有,這個request就會被加入到另一個NetworkQueue,所有真正准備進行網絡通信的request都在這裡,第一個可用的net線程會從NetworkQueue中拿出一個request扔向服務器。當響應數據到的時候,這個net線程會解析原始響應數據,寫入緩存,並把解析後的結果返回給主線程。如下圖:   所以,讀源碼的話也可以把源碼分成四層,如下圖:(其余的類都可以歸到“方便的工具類”中,比如ImageLoader,ClearCacheRequest等等)。

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved