編輯:關於android開發
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,響應監聽接口實例,錯誤監聽接口實例。
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等等)。
Android學習第五篇——動畫效果
Android學習第五篇——動畫效果 接下來我要介紹的是Android的一些動畫效果 一、AlphaAnimation透明動畫 這裡我用到了兩種不同的方法來實現透明動畫效
Android Activity的生命周期簡單總結
Android Activity的生命周期簡單總結 Android Activity的生命周期簡單總結 這裡的內容參考官方的文檔,這篇文章的目的不是去總結Activity
Android 手機衛士10--應用管理器,android10--
Android 手機衛士10--應用管理器,android10-- 1.添加不同類型條目 1 class MyAdapter extends BaseAdapter{
Exampleapp窗口大小調節,exampleapp窗口調節
Exampleapp窗口大小調節,exampleapp窗口調節 結構圖: 基類: package ch.halcyon.squareprogressbar.exampl