표준 요청 만들기

이번 강좌는 Volley가 지원하는 일반적인 요청 타입을 사용하는 방법을 다룹니다.

일반적인 요청타입으로는

  • StringRequest. 하나의 URL을 지정하여 가공되지 않은 문자열을 응답으로 받아옵니다. 예제는 '요청 큐 (Request Queue) 설정하기'에서 살펴보십시오.

  • ImageRequest 하나의 URL을 지정하여 이미지를 응답으로 받아옵니다.

  • JsonObjectRequest와 JsonArrayRequest(둘다 JsonRequest의 하위클래스 입니다)하나의 URL을 지정해 JSON 객체 또는 배열을 응답으로 받아옵니다.

만약 예상되는 응답의 종류가 위의 것 들 중 하나라면, 커스텀 요청을 사용하지 않아도 됩니다. 이번 강좌는 어떻게 표준형의 요청을 사용하는 법을 배웁니다. 어떻게 자신만의 커스텀 요청을 사용하는지 알고싶다면, '커스텀 요청 사용하기'를 확인해 주십시오.

이미지 요청하기

Volley 는 이미지들을 요청하기 위해서 아래의 클래스들을 제공합니다. 이러한 클래스들은 이미지 처리를 지원하는 정도에 따라 층계를 이루고 있습니다.

ImageRequest - 주어진 URL에서 이미지를 가져오는 요청을 하고 디코딩된 비트맵을 콜백하는 사전에 준비된(Canned) 요청입니다. 이것은 또한 특정 크기에 맞춰 이미지 크기를 재조절하는 것처럼 편리한 기능등을 제공합니다. 주요 이점으로는 Volley의 쓰레드 사용 계획에 있어 고비용의 이미지 처리(디코딩, 크기 재조정)가 자동으로 워커 쓰레드에서 발생하도록 하는 것입니다.

ImageLoader - 헬퍼 클래스로, 원격 URL들에서 이미지를 불러오고, 캐싱하는 동작을 처리합니다. ImageLoader는 많은 수의 ImageRequest들의 집합체(Orchestrator)입니다. 예를들면, 다수의 썸네일을 ListView에 넣을 때, 깜빡거림을 방지하기 위해서 보통의 Volley 캐시 이전에 인메모리 캐시(in-memory cache) 사용을 배치합니다. 이것은 메인쓰레드를 방해하거나 막지 않고 캐시를 사용할 수 있게 합니다(Cache hit). 이것은 디스크 I/O를 진행할 때는 불가능 한 것입니다. ImageLoader는 또한 응답 합성(Coalescing)을 합니다. 응답 합성이 없이 거의 모든 응답 핸들러(response handler)는 뷰에 비트맵을 넣거나, 이미지마다 레이아웃을 전달하는 것(layout pass)을 야기하게 됩니다. 응답합성은 다중의 응답을 동시에 전달하는 것을 가능하게 하여 성능 향상에 기여합니다.

NetworkImageView - URL을 통한 네트워크에서 이미지를 가져오는 경우에, ImageLoader에서 형성되어, 효과적으로 ImageView를 대체합니다. NetworkImageView는 또한 만약 해당 뷰가 뷰 계층에서 떼어지면, 연기된 요청들을 이와 연결된 연기된 요청들을 관리합니다.

ImageRequest 사용하기

ImageRequest의 예제입니다. ImageRequest는 URL로 지정된 이미지를 가져오고, 애플리케이션에 표시합니다. 아래의 예제는 싱글톤 클래스(요청 큐 사용하기에서 논의된 주제입니다.)를 통해 요청 큐로 상호작용하는 것의 한 부분입니다.

ImageView mImageView;
String url = "http://i.imgur.com/7spzG.png";
mImageView = (ImageView) findViewById(R.id.myImage);
...

//URL로 특정된 이미지를 가져오고 사용자 인터페이스(UI)에 표시합니다.
ImageRequest request = new ImageRequest(url,
    new Response.Listener<Bitmap>() {
        @Override
        public void onResponse(Bitmap bitmap) {
            mImageView.setImageBitmap(bitmap);
        }
    }, 0, 0, null,
    new Response.ErrorListener() {
        public void onErrorResponse(VolleyError error) {
            mImageView.setImageResource(R.drawable.image_load_error);
        }
    });
// 싱글톤 클래스의 요청 큐를 통해 접속합니다.
MySingleton.getInstance(this).addToRequestQueue(request);

ImageLoader와 NetworkImageView 사용하기

효율적으로 다수의 이미지를 표시하는 작업에, ImageLoader와 NetworkImageVIew를 사용할 수 있습니다. 예를들면, XML 레이아웃 파일에 있는 ListView에서 NetworkImageView를 마치 ImageVIew를 사용하는 것과 거의 동일한 방식으로 사용할 수 있습니다.

예제입니다.

<com.android.volley.toolbox.NetworkImageView
        android:id="@+id/networkImageView"
        android:layout_width="150dp"
        android:layout_height="170dp"
        android:layout_centerHorizontal="true" />

ImageLoader 자체를 이미지를 표시하는 것에 사용할 수 있습니다.
ImageLoader mImageLoader;
ImageView mImageView;
// 이미지를 불러올 URL입니다.
private static final String IMAGE_URL =
    "http://developer.android.com/images/training/system-ui.png";
...
mImageView = (ImageView) findViewById(R.id.regularImageView);

// 싱글톤 클래스에서 ImageLoader를 가져옵니다. 
mImageLoader = MySingleton.getInstance(this).getImageLoader();
mImageLoader.get(IMAGE_URL, ImageLoader.getImageListener(mImageView,
         R.drawable.def_image, R.drawable.err_image));

하지만 오로지 ImageView를 구성하는 경우라면, NetworkImageView로 이것을 진행할 수 있습니다.

ImageLoader mImageLoader;
NetworkImageView mNetworkImageView;
private static final String IMAGE_URL =
    "http://developer.android.com/images/training/system-ui.png";
...

// 화면에 이미지를 보이기 위해서 NetworkImageView를 가져옵니다.
mNetworkImageView = (NetworkImageView) findViewById(R.id.networkImageView);

// 싱글톤 클래스에서 ImageLoader를 가져옵니다
mImageLoader = MySingleton.getInstance(this).getImageLoader();

// 뷰에 넣어질 이미지의 URL을 설정합니다. 그리고 요청을 하기 위해 쓰일 ImageLoader를 입력합니다. 
mNetworkImageView.setImageUrl(IMAGE_URL, mImageLoader);

위의 짧은 발췌는 요청 큐 사용하기에서 나온 싱글톤 클래스를 통해서 요청 큐 (RequestQueue)와 ImageLoader에 접근합니다. 이 접근방법은 애플리케이션 생명주기 전체에 지속되는 단 하나의 인스턴스만 해당 클래스가 만들 것이라는 보장을 할 수 있습니다. 이 점이 특히 ImageLoader(불러오기와 이미지 캐싱을 처리하는 핼퍼 클래스 )의 사용에 있어 중요한데, 깜빡임 없는 화면 회전을 인메모리 캐시(in-memory Cache)의 주된 기능이기 때문입니다. 싱글톤 패턴을 사용하는 것은 액티비티와 별개로 비트맵 캐시가 유지되는 것을 가능하게 하기 때문입니다. 만약 ImageLoader를 액티비티에서 구현한다면, 기기가 회전하면서 매번 액티비티가 재생성될 때마다 ImageLoader가 재생성 될것입니다.이것은 깜빡임을 만들어냅니다.

LRU 캐시 예시

Volley의 toolbox는 표준의 캐시 사용을 디스크 기반 캐시(DiskBasedCache)로 제공합니다. 이 클래스는 하드 디시크의 특정 위치(directory)에 바로 파일들을 캐싱합니다. 그러니 ImageLoader를 사용하기 위해서, 반드시 커스텀 인메모리 LRU bitmap 캐시(custom in-memory LRU Bitmap Cache)를 제공해야 합니다. 해당 메모리는 ImageLoader.ImageCache 인터페이스를 구현합니다.(implements) 아마 싱글톤으로 캐시를 설정하고 싶을 겁니다. 싱글톤 패턴에 대한 자세한 내용은 '요청 큐 설정하기'를 확인하십시오.

아래는 인메모리 LruBItmapCache클래스를 사용한 예제입니다. LruCache를 상속하고(extends) ImageLoader.ImageCache 인터페이스를 구현하였습니다.(implements)

import android.graphics.Bitmap;
import android.support.v4.util.LruCache;
import android.util.DisplayMetrics;
import com.android.volley.toolbox.ImageLoader.ImageCache;

public class LruBitmapCache extends LruCache<String, Bitmap>
        implements ImageCache {

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

    public LruBitmapCache(Context ctx) {
        this(getCacheSize(ctx));
    }

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

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

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

    // 캐시 크기는 대략 세 화면을 구현할 수 있는 정도의 이미지와 동일하게 합니다. 
    public static int getCacheSize(Context ctx) {
        final DisplayMetrics displayMetrics = ctx.getResources().
                getDisplayMetrics();
        final int screenWidth = displayMetrics.widthPixels;
        final int screenHeight = displayMetrics.heightPixels;
        //pixel당 4 바이트입니다.
        final int screenBytes = screenWidth * screenHeight * 4;

        return screenBytes * 3;
    }
}

이 캐시를 사용해 Imageloader를 인스턴트화 하는 것은 다음과 같습니다.

RequestQueue mRequestQueue; // 존재한다 가정합니다.
ImageLoader mImageLoader = new ImageLoader(mRequestQueue, new LruBitmapCache(
            LruBitmapCache.getCacheSize()));

JSON 요청하기

Volley는 JSON요청을 위해 아래의 클래스들을 제공합니다.

JsonArrayRequest - 주어진 URL에서 JSONArray를 응답의 바디에 담아 가져옵니다.

JsonObjectRequest - 주어진 URL에서 JSONbject를 응답의 바디에 담아 가져옵니다. 요청의 바디의 한 부분으로 JSONObject를 담을 수 있는 선택지를 제공합니다.

두 클래스 모두 기본적 JsonRequest클래스에 근간을 두고 있습니다. 사용에 있어서 다른 요청들과 동일한 기본 패턴을 사용합니다. 아래의 예제는 JSON을 가져와 사용자 인터페이스에 표시하는 코드의 부분입니다.

TextView mTxtDisplay;
ImageView mImageView;
mTxtDisplay = (TextView) findViewById(R.id.txtDisplay);
String url = "http://my-json-feed";

JsonObjectRequest jsObjRequest = new JsonObjectRequest
        (Request.Method.GET, url, null, new Response.Listener<JSONObject>() {

    @Override
    public void onResponse(JSONObject response) {
        mTxtDisplay.setText("Response: " + response.toString());
    }
}, new Response.ErrorListener() {

    @Override
    public void onErrorResponse(VolleyError error) {
        // 자동으로 생성되는 메소드의 부분
    }
});

// 싱글톤 클래스로 요청 큐에 접근해야합니다.
MySingleton.getInstance(this).addToRequestQueue(jsObjRequest);

GSON를 이용해 커스텀 JSON요청 사용하기는 다음 강의인 커스텀 요청 사용하기에 나옵니다.

results matching ""

    No results matching ""