07/09/2018, 15:46

Android Working With Volley Library

Volley là một Networking Library để quản lý các request Network và lưu trữ những response không cần các Developer viết nhiều code như trước . Các tools bên trong Volley cho phép cùng một lúc thưc hiện nhiều request trên các thread khác nhau với các mức độ ưu tiên ( priority ) khác nhau. Tất ...

Volley là một Networking Library để quản lý các request Network và lưu trữ những response không cần các Developer viết nhiều code như trước .
Các tools bên trong Volley cho phép cùng một lúc thưc hiện nhiều request trên các thread khác nhau với các mức độ ưu tiên (priority ) khác nhau. Tất cả request được thực hiện và lưu trữ trong bộ nhớ cache giúp co việc reload lại dữ nhiều nhanh hơn. Toàn bộ response được lưu trong memory vậy nên nó không phải là 1 ý tưởng hay cho việc tải về những dữ liệu lớn như music hay movies. Nhưng nó lại là tuyệt với với những loại dữ liệu như JSON, Image, String …
Volley có rất nhiều tính năng, một vài trong số chúng là:

  • Xử lý request theo hàng đợi và độ ưu tiên
  • Hiệu quả cho việc sử dụng cache và quả lý bộ nhớ
  • Dễ dàng trong việc mở rộng và custom thư viện khi cần
  • Có khả năng cancel request
    Trước khi đọc tiếp hướng dẫn này, Tôi khuyên bạn nên xem bài trình bày bên dưới của Ficus Kirkpatrick tại Google I/O để có được sự tổng quan về volley

Download ****thư viện volley
Volley là thư việc mã nguồn mở của google, bạn có thể download trực tiếp từ github bằng dòng lại như bên dưới:
git clone https://android.googlesource.com/platform/frameworks/volley

Bạn có thể sử dụng volley như là một library project hay đơn giản bạn có thể tạo ra file volley.jar và copy nó vào trong folder libs của project
Creating Volley Singleton class
Cách tốt nhất để tạo một Request Queue là tạo ra một singleton class extends từ Application Object. Trong project tạo một class tên là ApplicationController.java extends từ class Application như bên dưới:

public class ApplicationController extends Application {

    public static final String LOG_TAG = ApplicationController.class.getSimpleName();
    private RequestQueue mRequestQueue;
    private ImageLoader mImageLoader;

    private static ApplicationController mInstance;

    @Override
    public void onCreate() {
        super.onCreate();
        mInstance = this;
    }

    public static synchronized ApplicationController getInstance(){
        return mInstance;
    }

    public RequestQueue getRequestQueue(){
        if (mRequestQueue == null) {
            mRequestQueue = Volley.newRequestQueue(getApplicationContext());
        }
        return mRequestQueue;
    }

    public ImageLoader getImageLoader(){
        getRequestQueue();
        if (mImageLoader == null) {
            mImageLoader = new ImageLoader(this.mRequestQueue, new LruBitmapCache());
        }
        return this.mImageLoader;
    }

    public void addToRequestQueue(Request request, String tag){
        //Set the default tag if tag is empty
        request.setTag(TextUtils.isEmpty(tag) ? LOG_TAG : tag);
        getRequestQueue().add(request);
    }

    public void addToRequestQueue(Request request){
        request.setTag(LOG_TAG);
        getRequestQueue().add(request);
    }

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

Tạo một class khác tên là** LruBitmapCache.** Class này dùng để xử lý cache image:

public class LruBitmapCache extends LruCache<String, Bitmap> implements 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 paramString){

        return get(paramString);
    }

    @Override
    public void putBitmap(String paramString, Bitmap paramBitmap){
        put(paramString, paramBitmap);

    }

}

Mở AndroidManifest.xml và add singleton class vào tag sử dụng thuộc tính android:name để thự thi class này bất kể khi nào khởi động ứng dụng. Ngoài ra thêm quyên truy cập Internet

Making JSON request

private void makeJsonObjectRequest(){

    JsonObjectRequest jsonObjRequest = new JsonObjectRequest(Method.GET,
            Const.URL_JSON_OBJECT_REQUREST, null,
            new Response.Listener<JSONObject>() {

                @Override
                public void onResponse(JSONObject response) {
                    Log.d(TAG, response.toString());
                    msgResponse.setText(response.toString());
                    hideProgressDialog();

                }
            }, new Response.ErrorListener() {

                @Override
                public void onErrorResponse(VolleyError error) {
                    VolleyLog.d(TAG,  "Error:" +error.getMessage() );
                }
            }){
        /* Passing some request headers*/
        @Override
        public Map<String, String> getHeaders()throws AuthFailureError {
            HashMap<String, String> headers = new HashMap<String, String>();
            headers.put("Content-Type", "application/json");
            return headers;
        }

        @Override
        protected Map<String, String> getParams()throws AuthFailureError {
            Map<String, String> params = new HashMap<String, String>();
            params.put("name", "Androidhive");
            params.put("email", "[email protected]");
            params.put("pass", "password123");
            return  params;
       }
    } ;

    // Adding request to request queue
    ApplicationController.getInstance().addToRequestQueue(jsonObjRequest, TAG_JSONOBJ_REQUEST);

}

Volley cung cấp một cách dễ dàng để tạo một json request. Nếu bạn càn một json object trả về bạn nên sử dụng JsonObjectRequest . Còn nếu bạn muốn trả về một json array trả về thì bạn nên dùng JsonArraryRequest.
Making json object request

private void makeJsonArrayRequest(){

    JsonArrayRequest jsonArrRequest = new JsonArrayRequest(Const.URL_JSON_ARRAY_REQUEST,
            new Response.Listener<JSONArray>() {

                @Override
                public void onResponse(JSONArray response) {
                    Log.d(TAG, response.toString());
                    msgResponse.setText(response.toString());
                    hideProgressDialog();

                }
            }, new Response.ErrorListener() {

                @Override
                public void onErrorResponse(VolleyError error) {
                    VolleyLog.d(TAG, "Error:" + error.getMessage());
                    hideProgressDialog();
                }
            });
    // Adding request to request queue
    ApplicationController.getInstance().adToRequestQueue(jsonArrRequest,TAG_JSONARR_REQUEST);
}

Making String request

StringRequest stringRequest = new StringRequest(Method.GET, Const.URL_STRING_REQUEST,
            new Response.Listener<String>() {

        @Override
        public void onResponse(String response) {
            Log.d(TAG, response.toString());
            msgResponse.setText(response.toString());
            hideProgressDialog();

        }
    }, new Response.ErrorListener() {

        @Override
        public void onErrorResponse(VolleyError error) {
            VolleyLog.d(TAG, "Error:"+ error.getMessage());
            hideProgressDialog();

        }
    });

    //Adding request to request queue
    ApplicationController.getInstance().addToRequestQueue(stringRequest, TAG_STRING_REQUEST);

Adding post parameters
Nó là rõ ràng rằng thỉng thoảng chúng ta submit một request với những parameter. Để làm điều đó chúng tao có thể override phương thức getParams(). Phương thức đó trả về một chuỗi parampeter trong định dạng key/value

@Override
protected Map<String, String> getParams()throws AuthFailureError {
    Map<String, String> params = new HashMap<String, String>();
    params.put("name", "Androidhive");
    params.put("email", "[email protected]");
    params.put("pass", "password123");
    return params;
}

Adding request headers
Giống như việc add parameter. Chúng ta cũng override phương thức getHeaders().
/* Passing some request headers*/

@Override
public Map<String, String> getHeaders()throws AuthFailureError {
    HashMap<String, String> headers = new HashMap<String, String>();
    headers.put("Content-Type", "application/json");
    return headers;
}

Making Image request
Volley giới thiệu một custom của** ImageView** được gọi là NetworkImageView để hiển thị Image từ url.
Loading image in NetworkImageView

ImageLoader imageLoader = ApplicationController.getInstance().getImageLoader();

// If you are using NetworkImageView

imgNetworkView.setImageUrl(Const.URL_IMAGE_REQUEST, imageLoader);

Loading image in ImageView
Nếu bạn muốn load Image vào trong** ImageView** thay vì sử dụng NetworkImageView
// If you are using normal ImageView

imageLoader.get(Const.URL_IMAGE_REQUEST, new ImageListener() {
@Override
public void onErrorResponse(VolleyError error) {
    VolleyLog.d(TAG, "Error:"+ error.getMessage());
}
@Override
public void onResponse(ImageContainer paramImageContainer, boolean paramBoolean) {
    // Load image into ImageView
    imageView.setImageBitmap(paramImageContainer.getBitmap());
}
});

Cancelling requests
Nếu bạn chú ý phương thức addToRequestQueue(request, tag) chấp nhận 2 tham số. một là request object , và 1 lần request tag . Tag được sử dụng để định danh request. Nếu tag giống nhau trong tất cả các request thì tất cả request sẽ bị cancel. Phương thức cancelAll() được sử dụng để cancel bất kỳ request nào.
Cancel single request

String tag_json_arry = "json_req";
ApplicationController.getInstance().getRequestQueue().cancelAll("feed_request");

Cancel all requests

ApplicationController.getInstance().getRequestQueue().cancelAll();

Request prioritization
Nếu bạn làm nhiều request trong cùng một thời điểm , bạn có thể xét độ ưu tiên đến các request để thực hiện những request quan trọng trước . Các cấp độ ưu tiên là** Normal, Low, Immediate** and High.

private Priority priority = Priority.HIGH;

StringRequest strReq = new     StringRequest(Method.GET,Const.URL_STRING_REQ,new Response.Listener() {

@Override
public void onResponse(String response) {
    Log.d(TAG, response.toString());
    msgResponse.setText(response.toString());
hideProgressDialog();

}
}, new Response.ErrorListener() {

@Override
public void onErrorResponse(VolleyError error) {
    VolleyLog.d(TAG, "Error: " + error.getMessage());
    hideProgressDialog();
}
}) {
@Override
public Priority getPriority() {
    return priority;
}
};

Bạn có thể download source code tại đây.

0