Ringster's Techblog

Tech, Mobile, Internet

Volley를 이용해 Network Data 전송하기 (2) – Request Queue 설정하기

leave a comment »

지난 포스팅(여기)에서 Volley를 이용하여 Network Data 전송을 하기 위해서는
1) RequestQueue 생성, 2) Request Object 생성,  3) 생성한 Object를 RequestQueue로 전달의 3단계가 필요하다고 하였다.
지난 포스팅에서는 RequestQueue를 생성하지 않고, Volley의 편의 메소드를 이용하여 RequestQueue를 생성하였는데,
이번에는 직접 RequestQueue를 생성하여 custom action을 가능하도록 하는 법을 알아보겠다.


1. Network 및 Cache 설정하기

RequestQueue는 작업을 위해 Request를 처리할 network 와 cache가 필요하다. volley는 toolbox에
one-file-per-response cache를 제공하는 DiskBasedCache와 개발자의 선택에 따라 AndroidHttpClient나
HttpURLConnection을 이용하는 BasicNetwork의 기본 구현을 제공한다. BasicNetwork는 HttpClient로
초기화되어야 하는데, 보통 HttpURLConnection이나 AndroidHttpClient가 쓰인다.

HttpURLConnection은 API Level 9 이하에서 안정적이지 않으므로 API Level 9 이하에서는 AndroidHttpClient를
사용하고, 이후에는 HttpURLConnection을 사용하도록 하려면 다음과 같이 기기가 어떤 Android Version에서
구동되는지 확인하는 코드를 이용한다.

HttpStack stack;
...
// If the device is running a version >= Gingerbread...
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {
    // ...use HttpURLConnection for stack.
} else {
    // ...use AndroidHttpClient for stack.
}
Network network = new BasicNetwork(stack);

 Volley에서는 기본적으로 API Level 9 이하에서는 AndroidHttpClient를 그 이후에는
HttpURLConnection을 이용한다.
그럼 Customized된 Request Queue를 이용해  SimpleRequest 전송 시와 동일한 동작을 하는 코드를 보자

public class MainActivity extends ActionBarActivity {
	private final String url = "http://www.google.com";
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		final TextView mTextView = (TextView) findViewById(R.id.text);
		
		RequestQueue mRequestQueue;

		// Instantiate the cache
		Cache cache = new DiskBasedCache(getCacheDir(), 1024 * 1024); // 1MB cap

		// Set up the network to use HttpURLConnection as the HTTP client.
		Network network = new BasicNetwork(new HurlStack());
		

		// Instantiate the RequestQueue with the cache and network.
		mRequestQueue = new RequestQueue(cache, network);

		// Start the queue
		mRequestQueue.start();

		// Formulate the request and handle the response.
		StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
		        new Response.Listener<String>() {
		    @Override
		    public void onResponse(String response) {
		    	mTextView.setText("Response is: "+ response.substring(0,500));
		    }
		},
		    new Response.ErrorListener() {
		        @Override
		        public void onErrorResponse(VolleyError error) {
		        	mTextView.setText(error.toString());
		    }
		});

		// Add the request to the RequestQueue.
		mRequestQueue.add(stringRequest);
	}
}

1회성 네트워크 작업을 할때는 RequestQueue를 생성한 후 RequestQueue.stop() 을 통해 작업을 종료시킬 수
있지만, 이러한 단순한 작업은 volley.newRequestQueue()를 이용하고 커스톰 RequestQueue는 Singleton으로
생성하여 App의 Lifetime 동안 존재하도록 구현하는 것이 일반적이다.

2. Singleton Pattern 사용하기

Application이 지속적으로 네트워크 작업을 한다면,  App의 Lifetime동안 존재할 RequestQueue 인스턴스가 있는
것이 효과적이다. 이는 여러가지 접근 방법을 통해 구현 가능한데 하나의 Singleton class를 생성하여
RequestQueue 및 사용할 volley function 들을 캡슐화하거나, Application의 Subclass를 생성하여 Application의
onCreate()메소드에서 requestQueue를 설정하면 된다.
두번째 방법보다는 첫번째 방법이  S/W의 모듈화에 좋으므로 첫번째 방법을 사용하기로 하며,
요점은 RequestQueue를 Activity context가 아닌 Application의 context를 통해 초기화하여
계속해서 재생성되지 않도록 하는 것이다.

 RequestQueue와 ImageLoader를 제공하는 Singleton Class를 생성해보자. (ImageLoader는 다음편에 설명)

public class MySingleton {
    private static MySingleton mInstance;
    private RequestQueue mRequestQueue;
    private ImageLoader mImageLoader;
    private static Context mCtx;

    private MySingleton(Context context) {
        mCtx = context;
        mRequestQueue = getRequestQueue();

        mImageLoader = new ImageLoader(mRequestQueue,
                new ImageLoader.ImageCache() {
            private final LruCache<String, Bitmap>
                    cache = new LruCache<String, Bitmap>(20);

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

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

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

    public RequestQueue getRequestQueue() {
        if (mRequestQueue == null) {
            // getApplicationContext() is key, it keeps you from leaking the
            // Activity or BroadcastReceiver if someone passes one in.
            mRequestQueue = Volley.newRequestQueue(mCtx.getApplicationContext());
        }
        return mRequestQueue;
    }

    public <T> void addToRequestQueue(Request <T> req) {
        getRequestQueue().add(req);
    }

    public ImageLoader getImageLoader() {
        return mImageLoader;
    }
}

이제 작성한 Singleton Class를 이용해 위해서 한 작업과 동일한 코드를 작성해보자.

public class MainActivity extends ActionBarActivity {
	private final String url = "http://www.google.com";
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		final TextView mTextView = (TextView) findViewById(R.id.text);
		
		// Get a RequestQueue
		RequestQueue queue = MySingleton.getInstance(this.getApplicationContext()).
		    getRequestQueue();
		
		// Formulate the request and handle the response.
		StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
		        new Response.Listener<String>() {
		    @Override
		    public void onResponse(String response) {
		    	mTextView.setText("Response is: "+ response.substring(0,500));
		    }
		},
		    new Response.ErrorListener() {
		        @Override
		        public void onErrorResponse(VolleyError error) {
		        	mTextView.setText(error.toString());
		    }
		});

		// Add a request (in this example, called stringRequest) to your RequestQueue.
		MySingleton.getInstance(this).addToRequestQueue(stringRequest);	
	}
}

이로서 Singleton pattern을 이용해 위에서 작성한 코드와 동일한 동작을 구현하였다.
다음 포스팅에서는 지금까지 사용해왔던 StringRequest를 비롯하여 ImageRequest, JSONObjectRequest 등
Standard Request를 사용하는 법을 알아보고, Singleton class에 추가한 ImageLoader의 사용법 또한 알아보겠다.

Advertisements

Written by Ringster

2014/12/03 , 시간: 11:03 오전

답글 남기기

아래 항목을 채우거나 오른쪽 아이콘 중 하나를 클릭하여 로그 인 하세요:

WordPress.com 로고

WordPress.com의 계정을 사용하여 댓글을 남깁니다. 로그아웃 / 변경 )

Twitter 사진

Twitter의 계정을 사용하여 댓글을 남깁니다. 로그아웃 / 변경 )

Facebook 사진

Facebook의 계정을 사용하여 댓글을 남깁니다. 로그아웃 / 변경 )

Google+ photo

Google+의 계정을 사용하여 댓글을 남깁니다. 로그아웃 / 변경 )

%s에 연결하는 중

Jay Jin, Programmer&Designer

Fork my brain because I'm ready to commit

쉐어보드

쉐어메이트에 관한 모든 것

jamesjungkuelee's biotech story

Biotech, entrepreneur, life

Communications as Ikor

기업 위기관리의 모든 것

Charles Pyo Ventures

시도와 실패, 성장의 기록. 2막에서도 계속되는 모험들.

VentureBeat

News About Tech, Money and Innovation

Open API, Cloud, DevOps 와 eBook

Open API, eBook, Cloud, DevOps

Economics of almost everything

Tech, Mobile, Internet

cylee

Tech, Mobile, Internet

gorekun.log

고어쿤로그

Google Developers Korea 블로그

Tech, Mobile, Internet

Android Developers Blog

Tech, Mobile, Internet

최피디의 앱스 개발기

기술, 앱스, SNS, 창업

D2 Blog

Tech, Mobile, Internet

All of Software

Tech, Mobile, Internet

'Startup's Story Platform’

'Startup's Story Platform’

%d 블로거가 이것을 좋아합니다: