Android網絡通信——Volley

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的用法

  1. 創建一個RequestQueue對象。
  2. 創建一個ImageLoader對象。
  3. 獲取一個ImageListener對象。
  4. 調用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) {

    }
}

效果:



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章