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