Volley
詳細代碼在這裏:longlong’s github
Another ways
- AsyncHttpClient,它把HTTP所有的通信細節全部封裝在了內部,我們只需要簡單調用幾行代碼就可以完成通信操作了。
Universal-Image-Loader,它使得在界面上顯示網絡圖片的操作變得極度簡單,開發者不用關心如何從網絡上獲取圖片,也不用關心開啓線程、回收圖片資源等細節。
Volley可是說是把AsyncHttpClient和Universal-Image-Loader的優點集於了一身,Volley在性能方面進行了大幅度的調整,它的設計目標就是非常適合去進行數據量不大,但通信頻繁的網絡操作,而對於大數據量的網絡操作,比如說下載文件等,Volley的表現就會非常糟糕。
注意
- mQueue只需要調用一次就行了Volley.newRequestQueue(this);這個方法內部會調用start方法,start方法默認開啓1個緩存線程,4個網絡請求線程。如果new多次了,那麼系統資源肯定最後要被耗盡啊。
mQueue如果能設置爲單例的就最好不過了,就不用頻繁的去創建銷燬線程了,佔用系統資源。Volley內部並沒有使用線程池來管理緩存線程和網絡請求線程。
如果mQueue沒有設置爲單例模式,那麼onDestroy方法必須調用Requ3.estQueue的stop方法,停止緩存線程和網絡請求線程。這兩個線程內部實現都是while無線循環的,除非調用了stop方法才退出while。想象一下,如果沒有stop,那麼啓動一個activity,如果要做網絡請求,那麼就new一個RequestQueue,就是創建5個線程出來,但是沒有去停止這幾個線程,所以一直累積累積,最後後果不堪設想。
添加訪問權限
<uses-permission android:name="android.permission.INTERNET" />
代碼詳解
1.Get方法
Get方法獲取String 發起一條HTTP請求,然後接收HTTP響應。
RequestQueue mQueue = Volley.newRequestQueue(this);
StringRequest stringRequest = new StringRequest("http://www.baidu.com",
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
Log.d("TAG", response);
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.e("TAG", error.getMessage(), error);
}
});
mQueue.add(stringRequest);
結果:返回給我們一長串的HTML代碼。
步驟
1. 創建一個RequestQueue對象。RequestQueue是一個請求隊列對象,它可以緩存所有的HTTP請求,然後按照一定的算法併發地發出這些請求。我們不必爲每一次HTTP請求都創建一個RequestQueue對象,這是非常浪費資源的,基本上在每一個需要和網絡交互的Activity中創建一個RequestQueue對象就足夠了。
2. 創建一個StringRequest對象。StringRequest的構造函數需要傳入三個參數,第一個參數就是目標服務器的URL地址,第二個參數是服務器響應成功的回調,第三個參數是服務器響應失敗的回調。其中,目標服務器地址我們填寫的是百度的首頁,然後在響應成功的回調裏打印出服務器返回的內容,在響應失敗的回調裏打印出失敗的詳細信息。
3. 將StringRequest對象添加到RequestQueue裏面。
2.Post方法
StringRequest中還提供了另外一種四個參數的構造函數,其中第一個參數就是指定請求類型的,我們可以使用如下方式進行指定:
StringRequest stringRequest = new StringRequest(Method.POST, url, listener, errorListener);
可是這只是指定了HTTP請求方式是POST,StringRequest中並沒有提供設置POST參數的方法,但是當發出POST請求的時候,Volley會嘗試調用StringRequest的父類——Request中的getParams()方法來獲取POST參數,所以,我們只需要在StringRequest的匿名類中重寫getParams()方法,在這裏設置POST參數就可以了,代碼如下所示:
StringRequest stringRequest = new StringRequest(Method.POST, url, listener, errorListener) {
@Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String> map = new HashMap<String, String>();
map.put("params1", "value1");
map.put("params2", "value2");
return map;
}
};
3.JsonRequest與JsonArrayRequest
RequestQueue mQueue = Volley.newRequestQueue(this);
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest("http://m.weather.com.cn/data/101010100.html", null,
new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
Log.d("TAG", response.toString());
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.e("TAG", error.getMessage(), error);
}
});
mQueue.add(jsonObjectRequest);
這樣當HTTP通信完成之後,服務器響應的天氣信息就會回調到onResponse()方法中,並打印出來。
4.ImageRequest的用法
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imageView = (ImageView)findViewById(R.id.imageView);
mQueue = Volley.newRequestQueue(this);
button = (Button)findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ImageRequest imageRequest = new ImageRequest(
"http://img.my.csdn.net/uploads/201404/13/1397393290_5765.jpeg",
new Response.Listener<Bitmap>() {
@Override
public void onResponse(Bitmap response) {
imageView.setImageBitmap(response);
}
}, 0, 0, Bitmap.Config.RGB_565, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
imageView.setImageResource(R.drawable.facebook);
}
});
mQueue.add(imageRequest);
}
});
}
效果:
ImageRequest的構造方法包含6個參數
- 參數1表示:圖片的URL地址
- 參數2表示:圖片請求成功的回調,這裏我們把返回的Bitmap參數設置到ImageView中
- 參數3、4表示:分別用於指定允許圖片最大的寬度和高度,如果指定的網絡圖片的寬度或高度大於這裏的最大值,則會對圖片進行壓縮,指定成0的話就表示不管圖片有多大,都不會進行壓縮。
- 參數5表示:用於指定圖片的顏色屬性,Bitmap.Config下的幾個常量都可以在這裏使用,其中ARGB_8888可以展示最好的顏色屬性,每個圖片像素佔據4個字節的大小,而RGB_565則表示每個圖片像素佔據2個字節大小.
- 參數6表示:圖片請求失敗的回調,這裏我們當請求失敗時在ImageView中顯示一張默認圖片。
5.ImageLoader的用法
- 創建一個RequestQueue對象。
- 創建一個ImageLoader對象。
- 獲取一個ImageListener對象。
- 調用ImageLoader的get()方法加載網絡上的圖片。
//創建一個RequestQueue對象。
RequestQueue mQueue = Volley.newRequestQueue(this);
//new出一個ImageRequest對象
//ImageLoader的構造函數接收兩個參數,第一個參數就是RequestQueue對象,第二個參數是一個ImageCache對象
//爲了體現第二個參數的功能 新建BitmapCache類,傳入參數
ImageLoader imageLoader = new ImageLoader(mQueue, new BitmapCache() {
@Override
public void putBitmap(String url, Bitmap bitmap) {
}
@Override
public Bitmap getBitmap(String url) {
return null;
}
});
//獲取一個ImageListener對象
ImageListener listener = ImageLoader.getImageListener(imageView,
R.drawable.default_image, R.drawable.failed_image);
//通過調用ImageLoader的getImageListener()方法能夠獲取到一個ImageListener對象,
//getImageListener()方法接收三個參數,
// 第一個參數指定用於顯示圖片的ImageView控件,
//第二個參數指定加載圖片的過程中顯示的圖片,
//第三個參數指定加載圖片失敗的情況下顯示的圖片。
//調用ImageLoader的get()方法來加載圖片
imageLoader.get("http://img.my.csdn.net/uploads/201404/13/1397393290_5765.jpeg", listener);
get()方法接收兩個參數:第一個參數就是圖片的URL地址,第二個參數則是剛剛獲取到的ImageListener對象。如果你想對圖片的大小進行限制,也可以使用get()方法的重載,指定圖片允許的最大寬度和高度:
imageLoader.get("http://img.my.csdn.net/uploads/201404/13/1397393290_5765.jpeg",
listener, 200, 200);
新建BitmapCache類,接口:ImageCache。
這裏只是簡單實現一下,如果想要寫一個性能非常好的ImageCache,最好藉助Android提供的LruCache功能。
public class BitmapCache implements ImageLoader.ImageCache {
private LruCache<String,Bitmap>mCache;
public BitmapCache(){
//將緩存圖片的大小設置爲10M
int maxSize = 10*1024*1024;
mCache = new LruCache<String,Bitmap>(maxSize){
@Override
protected int sizeOf(String key,Bitmap bitmap){
return bitmap.getRowBytes()*bitmap.getHeight();
}
};
}
@Override
public Bitmap getBitmap(String s) {
return null;
}
@Override
public void putBitmap(String s, Bitmap bitmap) {
}
}
效果: