간단한 요청보내기
고급 수준에선, Volley를 요청 큐 (Requesting Queue)를 작성하기 위해 그리고 이를 요청 객체에 전달하기 위해 사용합니다. 요청 큐는 네트워크 작업을 진행하기 위한 작동 쓰레드를 관리합니다. 캐시로부터 읽고 쓰며, 반응을 변환합니다. 요청들은 가공되지 않은 반응들을 변환합니다. 그리고 Volley는 메인 쓰레드로 빠르게 변환된 반응을 낚아채 전달합니다.
이번 강좌는 어떻게 Volley.newRequestQue의 편리한 메소드를 사용해서 요청을 보내는지 살펴봅니다. 해당 메소드는 RequstQueue를 만듭니다. 어떻게 RequestQueue를 직접 만드는 방법에 대한 정보는 다음 강좌인 요청 큐(Requesting Queue) 설정하기에서 얻으실 수 있습니다.
이 강좌는 또한 어떻게 요청을 요청 큐 에 추가하고 요청을 취소하는 방법을 보여줍니다.
인터넷 사용 권한 추가하기
Volley를 사용하기 위해서는 반드시 android.permission.INTERNET을 애플리케이션의 매니페스트에 추가해야 합니다. 이 권한 설정 없이는 네트워크 연결을 할 수 없을 것입니다.
//최근 안드로이드 스튜디오는 사용하는 패키지에 따라 자동으로 권한 설정을 추가하는 기능을 가지고 있습니다. 하지만 확실히 하기 위해 직접 추가하시는 것을 권장합니다.
newRequestQueue 사용하기
Volley는 Volley.newRequestQueue라는 편리한 메소드를 제공합니다. 이 메소드는 기본 값들을 사용해서 요청 큐를 생성하고 해당 큐를 실행합니다. 아래는 사용 예제입니다:
final TextView mTextView = (TextView) findViewById(R.id.text);
...
// 요청 큐의 인스턴스를 만듭니다.
RequestQueue queue = Volley.newRequestQueue(this);
String url ="http://www.google.com";
// 제공된 URL로부터 문자열의 응답을 받아옵니다.
StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
new Response.Listener<String>() {
//비동기 콜백함수입니다.
@Override
public void onResponse(String response) {
// 문자열 응답의 첫 500자를 표시합니다.
mTextView.setText("Response is: "+ response.substring(0,500));
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
mTextView.setText("That didn't work!");
}
});
// 해당 요청을 요청 큐에 추가합니다.
queue.add(stringRequest);
Volley는 항상 변환된 응답들을 메인 쓰레드에 전달합니다. 쉽게 사용자 인터페이스를 반응 핸들러를 통해서 직접 자유롭게 수정할 수 있기에, 메인 쓰레드에서 전달된 데이터를 사용해서 사용자 인터페이스를 구성하는 것이 편리합니다. 하지만 이것은 특히 요청을 취소하는 작업과 연관이 있는 라이브러리에서 제공되는 여러 의미(semantics)들에 있어서 결정적입니다.
'요청 큐(Requesting Queue)설정하기' 강좌에서 Volley.newRequestQueue대신 직접 큐를 구성하는 방법을 다룹니다.
요청 보내기
요청을 보내기 위해서는, 위에 나타난 것처럼 하나의 요청을 구성하고 요청 큐에 add()라는 메소드를 통해 추가하면 됩니다. 한 번 추가가 되면 파이프라인을 통해서 요청은 이동하고, 처리되며, 변환된 응답을 가져옵니다.
add()를 호출할 때, Volley는 하나의 캐싱 쓰레드와 네트워크 디스페치 쓰레드(a pool of network dispatch threads)를 실행합니다.큐에 요청을 추가할때, 캐싱 쓰레드에 의해 뽑히며, 선별됩니다. 즉 만약에 요청에 캐시에서 처리될 수 있으면, 캐시 처리된 응답이 캐시 쓰레드에서 변환되어 메인 쓰레드로 전달됩니다. 만약에 해당 요청이 캐시에 의해서 처리될 수 없다면, 네트워크 큐에 위치하게 됩니다. 첫번째 가용한 네트워크 쓰레드가 해당 요청을 큐로부터 얻어 HTTP 교환(Transaction)을 시행합니다. 워커 쓰레드에서 해당 응답이 변환되며, 응답을 캐시에 저장합니다. 그리고 변환된 응답을 메인 쓰레드로 전달합니다.
I/O을 막는 것과 같은 고비용 작업과 변환 또는 디코딩 작업은 워커 쓰레드에서 처리됨을 명심하십시오. 어떠한 쓰레드에서도 요청을 추가할 수 있으나 응답은 메인 쓰레드로만 전달됩니다.
그림1. 요청 과정
요청 취소하기
요청을 취소하기 위해선, cancel()을 Request객체에서 호출하면 됩니다. 한번 취소가 되면, Volley는 응답 핸들러가 절대 호출되지 않을 것을 확신하게 됩니다. 실제 이것은 모든 지연된 요청을 액티비티의 onStop() 콜백에서 취소할 수 있다는 것을 의미합니다. 그리고 액티비티가 null인지(getActivity() ==null) 또는 onSaveInstanceState()가 이미 호출되었는 지를 확인하는 것과 같은 방어 상용구(방어코딩)작성을 할 필요가 없습니다.
이러한 동작의 이점을 활용하기 위해서, 적절한 시기에 처리 중인 (in-Flight) 요청들을 취소하기 위해 이들을 추적해야 할것입니다. 한 가지 쉬운 방법이 있습니다. 태그 객체를 각각의 요청에 사용하면 됩니다. 이 태그들을 취소할 요청에 초점을 맞추는( scope)작업에 사용할 수 있습니다.예를 들어 모든 요청에 해당 요청이 만들어진 액티비티를 태그로 넣을 수 있습니다. 이러면 onStop()에서 requestQueue.cancelAll(this)호출로 관련 요청들을 취소할 수 있습니다. 유사하게, 한 ViewPager에서 생성된 모든 썸네일 이미지 요청에 해당 탭을 태그로 사용하여 밀어내기 동작에 요청을 취소할 수 있습니다. 이로써 새로운 다른 새로운 탭에서 다른 탭의 요청이 유지되는 것을 확실히 막을 수 있습니다.
아래의 예제는 문자열을 태그로 사용했습니다.
- 태그를 정의한 후 요청들에 첨가합니다.
public static final String TAG = "MyTag";
StringRequest stringRequest; // 해당 문자열 요청이 존재한다 가정합니다.
RequestQueue mRequestQueue; // 해당 요청 큐가 존재한다 가정합니다.
//요청에 태그를 첨가합니다
stringRequest.setTag(TAG);
// 요청큐에 요청을 추가합니다.
mRequestQueue.add(stringRequest);
- 액티비티의 onStop() )에서, 모든 요청을 해당 태그를 이용해 취소합니다.
@Override
protected void onStop () {
super.onStop();
if (mRequestQueue != null) {
mRequestQueue.cancelAll(TAG);
}
}
요청들을 취소할 때 주의하십시오. 만약에 경우에 따라 응답 핸들러가 상태를 진행하거나 또는 새로운 작업을 시작할지 결정한다면, 이를 고점을 고려해야합니다. 응답 핸들러는 요청이 취소되었을 때 호출되지 않습니다.
//