Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android網絡請求框架Volley學習

Android網絡請求框架Volley學習

編輯:關於Android編程

本文github地址:
https://github.com/YoungBear/MyBlog/blob/master/VolleyLearn.md

Volley是Android下個一個網絡請求庫,它可以讓Android下的網絡訪問更加簡單和快速。默認情況下,Volley都是異步訪問網絡的,所以我們不必擔心異步處理問題。

Volley的優點:

請求隊列和請求優先級 請求Cache和內存管理 擴展性性強 可以取消請求

導入Volley的方法

第一種

在build.gradle中添加dependency:

dependencies {
    ...
    compile 'com.android.volley:volley:1.0.0'
}

第二種

使用源代碼,作為一個library project。

git clone https://android.googlesource.com/platform/frameworks/volley

另外,也可以在源代碼中導出jar包,使用jar包作為庫。

使用Volley進行網絡請求

首先,在AndroidManifest.xml中添加網絡訪問權限,

使用一個單例來管理請求(一般可以繼承Application)

//VolleyController.java
public class VolleyController {

    public static final String TAG = VolleyController.class.getSimpleName();

    private static volatile VolleyController mInstance;
    private RequestQueue mRequestQueue;
    private ImageLoader mImageLoader;
    private static Context mContext;

    private VolleyController(Context context) {
        mContext = context.getApplicationContext();
        mRequestQueue = Volley.newRequestQueue(mContext);
        mImageLoader = new ImageLoader(mRequestQueue, new LruBitmapCache());
    }

    public static VolleyController getInstance(Context context) {
        if (mInstance == null) {
            synchronized (VolleyController.class) {
                if (mInstance == null) {
                    mInstance = new VolleyController(context);
                }
            }
        }
        return mInstance;
    }

    public RequestQueue getRequestQueue() {
        return mRequestQueue;
    }

    public ImageLoader getImageLoader() {
        return mImageLoader;
    }

    public  void addToRequestQueue(Request req, String tag) {
        req.setTag(TextUtils.isEmpty(tag) ? TAG : tag);
        mRequestQueue.add(req);
    }

    public  void addToRequestQueue(Request req) {
        req.setTag(TAG);
        mRequestQueue.add(req);
    }

    public void cancelPendingRequests(Object tag) {
        if (mRequestQueue != null) {
            mRequestQueue.cancelAll(tag);
        }
    }

}

還需要一個Cache來存放請求的圖片:

//LruBitmapCache.java
public class LruBitmapCache extends LruCache implements ImageLoader.ImageCache{

    public static int getDefaultLruCacheSize() {
        final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
        final int cacheSize = maxMemory / 8;
        return cacheSize;
    }

    public LruBitmapCache() {
        this(getDefaultLruCacheSize());
    }

    public LruBitmapCache(int sizeInKiloBytes) {
        super(sizeInKiloBytes);
    }

    @Override
    protected int sizeOf(String key, Bitmap value) {
        return value.getRowBytes() * value.getHeight() / 1024;
    }

    @Override
    public Bitmap getBitmap(String url) {
        return get(url);
    }

    @Override
    public void putBitmap(String url, Bitmap bitmap) {
        put(url, bitmap);
    }
}

String Request

新建一個Request並且把他加入到請求隊列中RequestQueue:

    private void simpleRequest() {

        StringRequest stringRequest = new StringRequest(
                Request.Method.GET,
                TEST_URL,
                new Response.Listener() {
                    @Override
                    public void onResponse(String response) {
                        Log.d(TAG, "onResponse, response: " + response);
                        txtDisplay.setText("Response is: " + response);
                    }
                },
                new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {
                        Log.d(TAG, "onErrorResponse, error: " + error.getMessage());
                        txtDisplay.setText("That didn't work!");
                    }
                });

        VolleyController.getInstance(this).addToRequestQueue(stringRequest, TAG);
    }

Volley工作原理圖

Life of a request

在Activity的onStZ喎?/kf/ware/vc/" target="_blank" class="keylink">vcCgpt723qNbQY2FuY2Vsy/nT0LHqvMfOqrjDVEFHtcTH68fzo7o8L3N0cm9uZz48L3A+DQo8cHJlIGNsYXNzPQ=="brush:java;"> @Override protected void onStop() { super.onStop(); VolleyController.getInstance(this).cancelPendingRequests(TAG); }

創建POST請求

上面說的都是GET請求,下面來說一下POST請求,與GET請求不同的是,只要在創建請求的時候將請求類型改為POST請求,並且override Request的getParams方法即可。

添加請求頭部信息

override Request的getHeaders方法。

    private void simplePostRequest() {
        StringRequest stringRequest = new StringRequest(
                Request.Method.POST,
                TEST_URL,
                new Response.Listener() {
                    @Override
                    public void onResponse(String response) {
                        Log.d(TAG, "post, onResponse, response: " + response);
                        txtDisplay.setText("Response is: " + response);
                    }
                },
                new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {
                        Log.d(TAG, "post, onErrorResponse, error: " + error.getMessage());
                        txtDisplay.setText("That didn't work!");
                    }
                }
        ) {
            @Override
            protected Map getParams() throws AuthFailureError {
                Map params = new HashMap();
                params.put("name", "Androidhive");
                params.put("email", "[email protected]");
                params.put("password", "password123");

                return params;
            }

            @Override
            public Map getHeaders() throws AuthFailureError {
                HashMap headers = new HashMap();
                headers.put("Content-Type", "application/json");
                headers.put("apiKey", "xxxxxxxxxxxxxxx");
                return headers;
            }
        };
        //關閉Cache
        stringRequest.setShouldCache(false);
        VolleyController.getInstance(this).addToRequestQueue(stringRequest, TAG);
    }

創建Image請求

Volley庫中自帶了NetworkImageView類,這個ImageView可以自動使用volley下載圖片。

使用ImageRequest

    private void imageRequest() {

        ImageRequest imageRequest = new ImageRequest(
                TEST_URL_1,
                new Response.Listener() {
                    @Override
                    public void onResponse(Bitmap response) {
                        mImageView.setImageBitmap(response);
                    }
                }, 0, 0, null,
                new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {
                        Log.d(TAG, "onErrorResponse, error: " + error.getMessage());
                    }
                }
        );
        VolleyController.getInstance(this).addToRequestQueue(imageRequest, TAG);
    }

ImageRequest構造函數源代碼:

    @Deprecated
    public ImageRequest(String url, Response.Listener listener, int maxWidth, int maxHeight,
            Config decodeConfig, Response.ErrorListener errorListener) {
        this(url, listener, maxWidth, maxHeight,
                ScaleType.CENTER_INSIDE, decodeConfig, errorListener);
    }

可以看到,ImageRequest的構造函數接收6個參數

第一個參數是圖片的URL地址 第二個參數是圖片請求成功的回調,這裡我們把返回的Bitmap參數設置到ImageView中 第三和第四個參數分別用於指定允許圖片最大的寬度和高度,如果指定的網絡圖片的寬度或高度大於這裡的最大值,則會對圖片進行壓縮,指定成0的話就表示不管圖片有多大,都不進行壓縮。 第五個參數用於指定圖片的顏色屬性,Bitmap.Config下的幾個常量都可以在這裡使用,其中ARGB_8888可以展示最好的顏色屬性,每個圖片像素占據4個人字節的大小,而RGB_565則表示每個圖片像素占據2個字節大小。 第六個參數是圖片請求失敗的回調,我們可以在請求失敗時顯示一張失敗的圖片。

使用ImageLoader

ImageLoader也可以用於加載網絡上的圖片,並且它的內部也是使用ImageRequest來實現的,不過ImageLoader明顯要比ImageRequest更加高效,因為它不僅可以幫我們對圖片進行緩存,還可以過濾掉重復的鏈接,避免重復發送請求。

由於ImageLoader已經不是繼承自Request的了,所以它的用法也和我們之前學到的內容有所不同,總結起來大致可以分為以下四步:

創建一個RequestQueue對象 創建一個ImageLoader對象 獲取一個ImageListener對象 調用ImageLoader的get()方法加載網絡上的圖片
    private void imageLoaderGet() {
        ImageLoader imageLoader = VolleyController.getInstance(this).getImageLoader();
        imageLoader.get(TEST_URL_3, new ImageLoader.ImageListener() {
            @Override
            public void onResponse(ImageLoader.ImageContainer response, boolean isImmediate) {
                mImageView3.setImageBitmap(response.getBitmap());
            }

            @Override
            public void onErrorResponse(VolleyError error) {
                Log.e(TAG, "Image Load Error: " + error.getMessage());
            }
        });
    }

使用NetworkImageView

NetworkImageView是一個自定義控件,它是繼承自ImageView的,具備ImageView控件的所有功能,並且在原生的基礎之上加入了加載網絡圖片的功能。

使用方法:

在布局文件中添加NetworkImageView 獲取ImageLoader 調用NetworkImageView的setImageUrl()方法
//...
    

    mNetworkImageView = (NetworkImageView) findViewById(R.id.network_img_display);
    private void setNetworkImageView() {
        ImageLoader imageLoader = VolleyController.getInstance(this).getImageLoader();
        mNetworkImageView.setImageUrl(TEST_URL_2, imageLoader);
    }

JSON Request

    private void jsonRequest() {
        JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(
                Request.Method.GET,
                TEST_URL,
                null,
                new Response.Listener() {
                    @Override
                    public void onResponse(JSONObject response) {
                        txtDisplay.setText(response.toString());
                    }
                },
                new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {
                        Log.e(TAG, "onErrorResponse, error: " + error.getMessage());
                    }
                });
        VolleyController.getInstance(this).addToRequestQueue(jsonObjectRequest, TAG);
    }

    private void jsonArrayRequest() {
        JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(
                Request.Method.GET,
                TEST_URL2,
                null,
                new Response.Listener() {
                    @Override
                    public void onResponse(JSONArray response) {
                        txtDisplay.setText(response.length() + "\n" + response.toString());
                    }
                },
                new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {
                        Log.e(TAG, "onErrorResponse, error: " + error.getMessage());
                    }
                }
        );
        VolleyController.getInstance(this).addToRequestQueue(jsonArrayRequest, TAG);
    }

自定義Requet

在build.gradle文件中添加gson依賴:

dependencies {
    ...
    compile 'com.google.code.gson:gson:2.7'
}

自定義GsonRequest:

//GsonRequest.java
public class GsonRequest extends Request {

    private final Gson gson = new Gson();
    private final Class clazz;
    private final Map headers;
    private final Response.Listener listener;

    public GsonRequest(String url, Class clazz, Map headers,
                       Listener listener, ErrorListener errorListener) {
        super(Method.GET, url, errorListener);
        this.clazz = clazz;
        this.headers = headers;
        this.listener = listener;
    }

    @Override
    public Map getHeaders() throws AuthFailureError {
        return headers != null ? headers : super.getHeaders();
    }

    @Override
    protected Response parseNetworkResponse(NetworkResponse response) {
        try {
            String json = new String(
                    response.data,
                    HttpHeaderParser.parseCharset(response.headers));
            return Response.success(
                    gson.fromJson(json, clazz),
                    HttpHeaderParser.parseCacheHeaders(response));
        } catch (UnsupportedEncodingException e) {
            return Response.error(new ParseError(e));
        } catch (JsonSyntaxException e) {
            return Response.error(new ParseError(e));
        }
    }

    @Override
    protected void deliverResponse(T response) {
        listener.onResponse(response);
    }

}

在實際調用的時候,和普通的請求類似:

    private void personRequest() {
        GsonRequest gsonRequest = new GsonRequest(
                TEST_URL,
                Person.class,
                null,
                new Response.Listener() {
                    @Override
                    public void onResponse(Person response) {
                        txtDisplay.setText("size: " + response.getContacts().size());

                    }
                },
                new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {
                        Log.e(TAG, "onErrorResponse, error: " + error.getMessage());
                    }
                }
        );
        VolleyController.getInstance(this).addToRequestQueue(gsonRequest, TAG);
    }

實體類Person類:(在AS下可以使用gson插件來生成)

package com.example.volleylearn.model;

import java.util.List;

/**
 * Created by youngbear on 16/10/18.
 */

public class Person {

    /**
     * id : c200
     * name : Ravi Tamada
     * email : [email protected]
     * address : xx-xx-xxxx,x - street, x - country
     * gender : male
     * phone : {"mobile":"+91 0000000000","home":"00 000000","office":"00 000000"}
     */

    private List contacts;

    public List getContacts() {
        return contacts;
    }

    public void setContacts(List contacts) {
        this.contacts = contacts;
    }

    public static class ContactsBean {
        private String id;
        private String name;
        private String email;
        private String address;
        private String gender;
        /**
         * mobile : +91 0000000000
         * home : 00 000000
         * office : 00 000000
         */

        private PhoneBean phone;

        public String getId() {
            return id;
        }

        public void setId(String id) {
            this.id = id;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public String getEmail() {
            return email;
        }

        public void setEmail(String email) {
            this.email = email;
        }

        public String getAddress() {
            return address;
        }

        public void setAddress(String address) {
            this.address = address;
        }

        public String getGender() {
            return gender;
        }

        public void setGender(String gender) {
            this.gender = gender;
        }

        public PhoneBean getPhone() {
            return phone;
        }

        public void setPhone(PhoneBean phone) {
            this.phone = phone;
        }

        public static class PhoneBean {
            private String mobile;
            private String home;
            private String office;

            public String getMobile() {
                return mobile;
            }

            public void setMobile(String mobile) {
                this.mobile = mobile;
            }

            public String getHome() {
                return home;
            }

            public void setHome(String home) {
                this.home = home;
            }

            public String getOffice() {
                return office;
            }

            public void setOffice(String office) {
                this.office = office;
            }
        }
    }
}

測試代碼位置:https://github.com/YoungBear/VolleyLearn

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