2013년 11월 17일 일요일

Google Volley 의 기능들과 사용법 (코드 예제)


Volley의 주 기능과 장점

* 하나의 requestQueue 모든 요청들을 처리한다
     -알아서 동시다발적으로 요청을 할수있다

* 우선 순위 설정을 할수 있다.
     -이미지 파일들은 기본적으로 낮은 우선순위를 가진다.
     -Priority class 를 상속하여 우선순위를 customize 할 수도 있다.

* 리퀘스트를 취소할 수도 있다. ( ListView 에서 유저가 빠르게 스크롤링 할 경우, 스크롤링 한 내용을 다 로딩할 필요가 없고, 보여지는 부분 이외에 로딩이 안된 리퀘스트들은 취소할 수 있다. )
      -Volley 가 알아서 자동으로 처리한다.

* 프로요 버전의 HttpURLConnection에 있는 버그를 해결해준다.


* NetworkImageView 클래스가있다.

     -imageLoader 구현
     -이미지로딩 요청들을 모았다하 하나로 묶어서 보내준다.
     -캐싱 기능
     -이미지 스케일링 기능 (훨씬 빠른 로딩이 가능하다)
     -병행 (동시다발적) 이미지 로딩 - 핸드폰의 코어수 만큼의 로딩하여 최적화 함.

Volley 가 작동하는 법!

     



처음 리퀘스트를 생성하고 큐에 넣으면, 우선순위에 맞추어 캐시 큐로 들어간다.
그 후, 리퀘스트가 큐에서 나올 차례가 되면, CacheDispatcher 가 리퀘스트를 빼간다.
그럼 Volley는 리퀘스트에 대한 결과값이 캐시에서 가져올 수 있는지 확인한다. (hit 화살표)
만약 가져올수 없으면 miss 다. (miss 화살표)

캐시 hit 의 경우, 캐시에서 결과 값을 읽어온 후 파싱을 하고 response를 던진다.

miss 의 경우, NetworkResponse에서 리퀘스트를 받아서 넷상으로 request를 보내고 결과 값을 받아 파싱한다.

코드 예제
Volley를 쓰려면 기본적으로 3 단계를 거친다.:
1. RequestQueue  를 만든다.
2. Reuest를 만든다.
3. Request를 RequestQueue 에 넣는다.

1. RequestQueue 를 Singleton 형식으로 만든다.
Volley는 하나의 Queue에서 모든 요청을 처리하므로, Queue는 하나만 만들어 쓰면 되기에 Singleton 패턴을 쓴다.


public class VolleySingleton {
    private static VolleySingleton mInstance = null;
    private RequestQueue mRequestQueue;
    private ImageLoader mImageLoader;

    private VolleySingleton(Context context){
        mRequestQueue = Volley.newRequestQueue(context);
        mImageLoader = new ImageLoader(this.mRequestQueue, new ImageLoader.ImageCache() {
            private final LruCache mCache = new LruCache(10);
            public void putBitmap(String url, Bitmap bitmap) {
                mCache.put(url, bitmap);
            }
            public Bitmap getBitmap(String url) {
                return mCache.get(url);
            }
        });
    }

    public static VolleySingleton getInstance(Context context){
        if(mInstance == null){
            mInstance = new VolleySingleton(context);
        }
        return mInstance;
    }

    public RequestQueue getRequestQueue(){
        return this.mRequestQueue;
    }

    public ImageLoader getImageLoader(){
        return this.mImageLoader;
    }
}

2. Http Request를 구현한다.
1)미리 Type이 정의된 리퀘스트의 경우
생성자 파라미터로  int Request.Method.(GET or POST), String url, T Content, Response Listener, Response ErrorListener 를 받는다.
new JsonObjectRequest( //JsonArrayRequest and StringRequest(call API in URI) is the same
                Request.Method.POST, "url", null,
                new Response.Listener() {
                    @Override
                    public void onResponse(JSONObject jsonObject) {

                    }
                },
                new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError volleyError) {

                    }
                }
        );
    };
2)커스텀 Request (JsonRequest or Request)의 경우
      1 - JsonRequest는 parsenetworkResponse 메소드에서 결과값인 NetworkResponse를 파싱 해주어야 한다.

    JsonRequest jsonRequest = new JsonRequest(Request.Method.POST, "url", "requestBody",
            new Response.Listener() {
                @Override
                public void onResponse(JSONArray jsonArray) {

                }
            },
            new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError volleyError) {

                }
            })
    {
        @Override
        protected Response parseNetworkResponse(NetworkResponse networkResponse) {
            try{
                String json = new String(networkResponse.data, HttpHeaderParser.parseCharset(networkResponse.headers));
                return Response.success(
                        new JSONArray(json), HttpHeaderParser.parseCacheHeaders(networkResponse)
                );
            }
            catch(UnsupportedEncodingException e){
                return Response.error(new ParseError(e));
            }
            catch(JSONException e){
                return Response.error(new ParseError(e));
            }
        }
    };
-2 Request 의 경우에도 parseNetworkResponse 에서 파싱을 해주고, deliverResponse에서 Response 리스너가 반응하는 함수를 넣어주어야 한다.

    Request integerRequest = new Request(Request.Method.POST, "url", new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError volleyError) {

        }
    }) {
        @Override
        protected Response parseNetworkResponse(NetworkResponse networkResponse) {
            try {
                Integer i = new Integer(new String(networkResponse.data, HttpHeaderParser.parseCharset(networkResponse.headers)));
                return Response.success(i, HttpHeaderParser.parseCacheHeaders(networkResponse));
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        }

        @Override
        protected void deliverResponse(Integer integer) {
             listener.onResponse(integer);
        }
    };
3) 이미지 요청은 URL 과 위의 Singleton 에 있는 ImageLoader를 이용하여 요청한다.
    ImageRequest a = new ImageRequest("url", new Response.Listener() {
        @Override
        public void onResponse(Bitmap bitmap) {

        }
    }, /*maxWidth*/0, /*maxHeight*/ 0, Bitmap.Config.ARGB_8888, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError volleyError) {
        }
    });
또는 XML 레이아웃파일에 com.android.volley.toolbox.networkimageview 를 넣어놓고 Java에서 뷰를 부른 후, 아래와 같은 형식으로 요청한다.
    mImageView.setImageUrl(URL, mImageLoader);
(자동으로 큐에 들어가므로 더욱 간단하다.)

3. 생성한 Request를 큐에 넣는다.
VolleySingleton.getInstance(mContext).getRequstQueue().add(request);


참고 자료:
     Youtube - Google I/O 2013 - Volley: Easy, Fast Networking for Android
                    http://www.youtube.com/watch?v=yhv8l9F44qo
     Setting up the Android Google Volley ImageLoader for NetworkImageView
          http://cypressnorth.com/mobile-application-development/setting-android-google-volley-imageloader-networkimageview/ 
     [android] Volley - Network & ImageLoading 라이브러리 ( google I/O 2013 )     
          http://hanburn.tistory.com/135

댓글 없음:

댓글 쓰기