본문 바로가기

프로그래밍

Android Asynchronous Http Client - 안드로이드 비동기 http 라이브러리

비동기 요청

Android Asynchronous Http Client는 콜백 패턴으로 구성된 Http Client 라이브러리 입니다. 아파치의 HttpClient에 기반하여 만들어 졌다고 합니다. 모든 요청은 UI 쓰레드 바깥에서 비동기적으로 행해집니다. 요청을 하고 나서 응답을 받으면 콜백 로직으로 응답을 넘겨 줍니다. 이때 콜백 로직은 콜백을 생성한 곳과 같은 쓰레드에서 실행됩니다. 안드로이드의 message Handler를 이용하여 구현했다고 합니다. 덕분에 보통 웹 요청을 할때 부딪치게 되는 골치아픈 쓰레드 관리 문제를 피할 수 있게 됩니다. 우리는 그저 Client를 생성하고 웹에 요청하고 콜백 메쏘드를 만들어 응답을 받기만 하면 되는 것입니다. 어떠한 쓰레드 관리도 할 필요가 없게됩니다. 또한 쓰레드를 동기화 하지 않아서 어떠한 락도 존재하지 않습니다.


강력한 기능들

단순히 비동기 요청만 할 수 있는 라이브러리는 아닙니다. 몇가지 강력한 기능들도 함께 제공됩니다. 

Request Params Builder

요청을 할때 인자들을 굉장히 쉽게 추가할 수 있습니다. GET 메쏘드에 들어가는 인자나 POST 메쏘드에 들어가는 인자는 모두 똑같은 방법으로 만들 수 있습니다. 라이브러리가 요청을 처리할때 알아서 Params들을 GET 메쏘드나 POST 메쏘드에 맞게 변형시켜 줍니다. 요청에 사용되는 인자들은 RequestParams이라는 클래스를 이용하여 쉽게 생성할 수 있습니다. 생성하는 방법은 여러가지가 있습니다. RequestParams에 put 메쏘드를 이용하여 key/value 값으로 집어 넣을 수 있고, 따로 Map 객체를 만들어 RequestParams에게 넘겨줄 수 도 있습니다.

// RequestParams 생성
RequestParams params = new RequestParams();
params.put("key", "value");
params.put("more", "data");

// 인자가 하나라면 RequestParams를 생성할떄 인자로 넘겨줄 수 있다.
RequestParams params = new RequestParams("single", "value");

// Map을 RequestParams에 넘겨줘도 된다.
HashMap paramMap = new HashMap();
paramMap.put("key", "value");
RequestParams params = new RequestParams(paramMap);

RequestParams에 대한 자세한 내용은 RequestParams Javadoc에서 확인할 수 있습니다.

Multipart File Upload

안드로이드에서 Multipart File Upload 기능을 구현하려면 여간 까다로운 것이 아닙니다. Android Asynchronous Http Client는 이러한 어려움을 굉장히 쉽게 해결할 수 있는 방법을 제공합니다. Request params에 InputStream 객체나 File 객체를 value로 집어 넣으면 됩니다. String, int, boolean와 같은 방법으로 사용할 수 있어서 굉장히 편리합니다. File 처리에 대한 추상화가 잘 되어 있어 다른 값들과 똑같은 방법으로 params에 집어 넣을 수 있다는게 굉장히 인상적입니다.

ile myFile = new File("/path/to/file.png");
RequestParams params = new RequestParams();
try {
    params.put("profile_picture", myFile);
} catch(FileNotFoundException e) {}

Persistent Cookie Storage

이것도 너무 멋있는 기능인것 같습니다. 쿠키를 로컬에 저장하여 쿠키를 영속적으로 유지시킬 수 있습니다. 안드로이드에서 간단한 데이터 저장에 사용되는 SharedPreferences를 이용하여 라이브러리가 알아서 쿠키를 저장합니다. 이 기능을 사용하면 사용자가 앱을 종료하고 다시 실행해도 로그인이 유지될 수 있습니다. 자동로그인 기능을 따로 구현할 필요가 없어지는 것이지요. (물론 서버에서 일정 시간이 지날때 세션을 종료시킨다면 일정 시간 단위로 계속 로그인을 해야합니다.) 또한 원하는 쿠키를 마음대로 만들어 cookie storage에 넣어 저장할 수 있습니다.

PersistentCookieStore myCookieStore = new PersistentCookieStore(this);
myClient.setCookieStore(myCookieStore);

// 마음대로 쿠키를 조작할 수 있다.
BasicClientCookie newCookie = new BasicClientCookie("cookiesare", "awesome");
newCookie.setVersion(1);
newCookie.setDomain("mydomain.com");
newCookie.setPath("/");
myCookieStore.addCookie(newCookie);

다양한 응답 Handler

서버에서 응답이 오면 사용자는 응답을 적절한 형태로 Parse 하여 사용해야 합니다. Android Asynchronous Http client에서는 알아서 Parsing을 해줍니다. 라이브러리가 제공하는 Handler를 3가지 입니다. AsyncHttpResponseHandler, JsonHttpResponseHandler, BinaryHttpResponseHandler가 그 3가지 입니다. AsyncHttpResponseHandler는 String 형태로 응답을 돌려줍니다. JsonHttpResponseHandler는 응답을 JsonObject 객체로 재구성하여 돌려줍니다. 이 기능 떄문에 Json응답을 다루기가 굉장히 편해집니다. BinaryHttpResponseHandler는 byte array를 돌려줍니다. 이 기능을 이용하면 파일 다운로드 기능을 구현하기가 쉬워지죠. binary 파일을 byte array로 알아서 변환해 주기 때문에 우리가 할 일은 그 byte array를 로컬에 저장하는 일 뿐입니다.

class TwitterRestClientUsage {
    public void getPublicTimeline() throws JSONException {
        TwitterRestClient.get("statuses/public_timeline.json", null, new JsonHttpResponseHandler() {
            @Override
            public void onSuccess(JSONArray timeline) {
                // Pull out the first event on the public timeline
                JSONObject firstEvent = timeline.get(0);
                String tweetText = firstEvent.getString("text");

                // Do something with the response
                System.out.println(tweetText);
            }
        });
    }
}

// 파일을 다운로드하자
AsyncHttpClient client = new AsyncHttpClient();
String[] allowedContentTypes = new String[] { "image/png", "image/jpeg" };
client.get("http://example.com/file.png", new BinaryHttpResponseHandler(allowedContentTypes) {
    @Override
    public void onSuccess(byte[] fileData) {
        // Do something with the file
    }
});

Basic Auth Credentials

Android Asynchronous Http Client는 기본적인 인증 기능을 내장하고 있습니다. Basic Auth를 설정해 두면 어떤 요청을 할때 인증이 필요하다면 알아서 인증을 하게 됩니다. 

AsyncHttpClient client = new AsyncHttpClient();
client.setBasicAuth("username","password/token");
client.get("http://example.com");

그 외의 기능들

  • gzip 응답을 받으면 자동으로 압축을 해제하여 응답을 돌려줍니다.
  • 라이브러리 사이즈가 25kb밖에 하지 않습니다.
  • 재요청이 모바일 환경에 최적화 되어있다고 합니다.

마치며

안드로이드에서 사용되는 많은 Http Client 라이브러리들이 있지만, Android Async Http Client 처럼 강력하면서 편리하면서도 안정적인 라이브러리는 없을것 같습니다. 정말 팔방미인인 라이브러리입니다. 예전에 안드로이드에서 웹 요청을 구현하면서 요청을 일일히 코딩해서 만들고, 수 많은 쓰레드 문제들과 싸워왔던 과거가 주마등처럼 앞에 지나가네요. 하지만 그런 일들은 이제 모두 추억일 뿐입니다.