標籤:android style class blog code http
本文內容
- 什麼是 Volley 庫
- Volley 能做什麼
- Volley 架構
- 示範 Volley 庫的使用
- 參考資料
Android 關於網路操作一般都會介紹 HttpClient 以及 HttpConnection 這兩個包。前者是 Apache 開源庫,後者是 Android 內建 API。企業級應用,一般都會選擇使用已經封裝好的 http 架構。比較流行有 Volley、android-async-http、retrofit、okhttp、androidquery、AndroidAsync 等。他們各有特點,不同的架構有不同的效率,如今 Google 推出了官方的針對 Android 平台上的網路通訊庫 Volley,能使網路通訊更快,更簡單,更健壯,Volley 在提供了高效能網路通訊功能的同時,對網狀圖片載入也提供了良好的支援,完全可以滿足簡單 REST 用戶端的需求。另外,但 Volley 擴充性很強,可以根據需要定製你自己的網路請求。
什麼是 Volley 庫
Volley 是 Ficus Kirpatrick 在 Gooogle I/O 2013 發布的一個處理和緩衝網路請求的庫,能使網路通訊更快,更簡單,更健壯。Volley 名稱的由來 a burst or emission of many things or a large amount at once。在Gooogle I/O 2013 演講上,其配圖是一幅火弓箭。 1 所示。
圖 1 Gooogle I/O 2013 Volley
Volley 管理著處理和緩衝網路請求,它節省了開發人員的寶貴時間,一次又一次編寫相同的網路調用/緩衝代碼。更少的重複代碼,其中一個好處就是減少了 bug,這是所有開發人員所期望的。
所謂“一次又一次編寫相同的網路調用/緩衝代碼”,就是 AsyncTask 以及你編寫的通過 Web API 擷取響應,並顯示出來的邏輯/代碼。我們必須在 ProgressBar() 和 onPostExecute() 方法內照顧 ProgressBar/ProgressDialog 。雖然這不是一個艱巨的任務,但卻很無聊,甚至感到厭倦,儘管我已經定義了 BaseTask 類來管理ProgressBar/ProgressDialog 的顯示/取消,以及更多其它操作。現在,Volley 是替代 AsyncTask 的強大工具。
Volley 能做什麼
Volley 適合小而快的資料轉送,特別是針對以下兩種情況:
Volley 優勢:
- Volley 可以自動安排所有的網路請求。這意味著 Volley 會照顧你 APP 執行的從 Web 擷取響應或圖片所有的網路請求。
- Volley 提供透明的磁碟和記憶體緩衝。
- Volley 提供強大的取消請求的 API。這意味著你可以取消一個單獨的請求,或是你可以設定取消請求的塊(可以為多個)或範圍。
- Volley 提供強大的自定功能。
- Volley 提供調試和追蹤工具。
Volley 架構
Volley 使用了線程池來作為基礎結構,主要分為主線程,cache 線程和 network 線程。主線程和 cache 線程都只有一個,而 NetworkDispatcher 線程可以有多個,這樣能解決比並行問題。
圖 2 Volley 架構
示範 Volley 庫的使用
下載示範,將 Volley 庫和示範項目匯入到 eclipse 裡,再將 Volley 庫添加到示範項目。程式運行結果 3 所示,包含兩個示範:網路擷取 JSON 和 圖片。
圖 3 左:程式主介面;中:點擊“擷取 JSON”;右:點擊“擷取 Image”
主程式 activity_main.xml 介面包含兩個按鈕,顯示兩個示範的 activity,核心代碼如下所示:
public class MainActivity extends Activity {
Intent intent = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.btn_json).setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View v) {
intent = new Intent(MainActivity.this, JsonDemo.class);
startActivity(intent);
}
});
findViewById(R.id.btn_img).setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View v) {
intent = new Intent(MainActivity.this, ImgDemo.class);
startActivity(intent);
}
});
}
}
擷取 JSON
通過 Volley 訪問國家氣象局提供的 JSON 介面,獲得北京的天氣狀況。
- http://www.weather.com.cn/data/sk/101010100.html
http://www.weather.com.cn/data/cityinfo/101010100.html
http://m.weather.com.cn/data/101010100.html
其中,101010100 代表北京。
activity_json.xml 分頁檔包含一個 TextView 控制項和一個 ProgreeBar 控制項,略,核心代碼如下所示:
package com.example.volleyexample;
import android.app.Activity;
import org.json.JSONObject;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonObjectRequest;
import com.android.volley.toolbox.Volley;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
public class JsonDemo extends Activity {
private TextView txtDisplay;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_json);
txtDisplay = (TextView) findViewById(R.id.txtDisplay);
RequestQueue queue = Volley.newRequestQueue(this);
String url = "http://www.weather.com.cn/data/sk/101010100.html";
JsonObjectRequest jsObjRequest = new JsonObjectRequest(
Request.Method.GET, url, null,
new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
// TODO Auto-generated method stub
txtDisplay.setText("Response => " + response.toString());
findViewById(R.id.progressBar1)
.setVisibility(View.GONE);
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
// TODO Auto-generated method stub
}
});
queue.add(jsObjRequest);
}
}
擷取 image
activity_img.xml 分頁檔包含兩個控制項:ImageView 和 NetworkImageView,其中,NetworkImageView 是 Volley 提供的控制項,畢竟載入圖片的使用頻率很高,略,核心代碼如下所示:
package com.example.volleyexample;
import org.json.JSONObject;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.ImageLoader;
import com.android.volley.toolbox.ImageLoader.ImageCache;
import com.android.volley.toolbox.ImageLoader.ImageListener;
import com.android.volley.toolbox.NetworkImageView;
import com.android.volley.toolbox.Volley;
import android.app.Activity;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.support.v4.util.LruCache;
import android.widget.ImageView;
public class ImgDemo extends Activity {
String url = "http://images.cnblogs.com/cnblogs_com/liuning8023/588559/o_Android.jpg";
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_img);
RequestQueue mRequestQueue = Volley.newRequestQueue(this);
final LruCache<String, Bitmap> mImageCache = new LruCache<String, Bitmap>(
20);
ImageCache imageCache = new ImageCache() {
@Override
public void putBitmap(String key, Bitmap value) {
mImageCache.put(key, value);
}
@Override
public Bitmap getBitmap(String key) {
return mImageCache.get(key);
}
};
ImageLoader mImageLoader = new ImageLoader(mRequestQueue, imageCache);
// ImageView
ImageView img = (ImageView) findViewById(R.id.imgView);
ImageListener listener = ImageLoader
.getImageListener(img, android.R.drawable.ic_menu_rotate,
android.R.drawable.ic_delete);
mImageLoader.get(url, listener);
// NetworkImageView
NetworkImageView netImgView = (NetworkImageView) findViewById(R.id.networkImgView);
netImgView.setTag("url");
netImgView.setImageUrl(url, mImageLoader);
}
}
參考資料
- Android Async HTTP Clients: Volley vs Retrofit
- Android Volley
- Android Volley Examples
下載 Demo