Android 앱 개발을 하면서 서버와 통신을 위해 네트워크 기능을 쓸 경우가 대다수이다.


기존 네트워크 기능을 위해 HttpURLConnectionHttpClient (OS 6.0 부터 삭제) 등이 쓰여왔고, OS 3.0 (API 11) 이후에 


NetworkOnMainThreadException 를 피하고자 Thread, AsyncTask 등을 사용하기도 했다.


그 후 여러 편의성을 제공하는 통신 라이브러리 들이 등작하였다. OkHttp, Volley (설명), Retrofit ... (라이브러리 비교)


그 중에서 최근까지 많이 쓰이고 있는 Retrofit에 대해서 초간단 맛만 보기로 하자.


0. 준비물 : API, Android Studio, 잠시나마 집중하겠다는 마음가짐.


1. API

직접 준비하기 어려울 경우 공개되어 있는 고마운 API들을 찾아서 사용해보자. 

예를 들면 빗썸 OPEN API 같은... 


연습을 위해 https://api.bithumb.com/public/ticker/{currency}를 사용해보자.


2. build.gradle 설정

dependencies에 retrofit 최신버전을 추가한다. (Gson 사용을 위해 Gson 관련 추가한다.)


dependencies {
    compile 'com.google.code.gson:gson:2.8.2'                 // Gson 사용시
    compile 'com.squareup.retrofit2:retrofit:2.3.0'
    compile 'com.squareup.retrofit2:converter-gson:2.3.0'     // Gson 처리시
    compile 'com.squareup.retrofit2:converter-scalars:2.3.0'  // String 처리시
    ...
}


3. Data 클래스 

결과 JSON에 맞춰 Data 클래스를 생성하자. (Json to Java Object 서비스)


public class BithumbTickerData {
    @SerializedName("opening_price")
    public String openingPrice;
    @SerializedName("closing_price")
    public String closingPrice;
    @SerializedName("min_price")
    public String minPrice;
    @SerializedName("max_price")
    public String maxPrice;
    @SerializedName("average_price")
    public String averagePrice;
    @SerializedName("units_traded")
    public String unitsTraded;
    @SerializedName("volume_1day")
    public String volume1day;
    @SerializedName("volume_7day")
    public String volume7day;
    @SerializedName("buy_price")
    public String buyPrice;
    @SerializedName("sell_price")
    public String sellPrice;
    @SerializedName("date")
    public long date;
}

public class BithumbTicker {
    @SerializedName("status")
    public String status;
    @SerializedName("data")
    public BithumbTickerData data;
}


4. interface 생성

API Method 방식 및 Path에 대해서 정의하자.


    public interface OpenApiService {
        @GET("public/ticker/{path}")
        Call tickerInfo(@Path("path") String path);
    }


5.1. Retrofit 초기화

Retrofit 생성 후 사용할 interface를 통해 서비스를 만들자. (Response를 String 형태로 받고 싶다면 ScalarsConverterFactory 사용)


        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("https://api.bithumb.com/")
                .addConverterFactory(GsonConverterFactory.create())        // Gson 처리시
                //.addConverterFactory(ScalarsConverterFactory.create())  // String 등 처리시
                .build();
        OpenApiService openApiService = retrofit.create(OpenApiService.class);


5.2. Call 생성

만들어 둔 interface를 호출하는 Call을 생성하자.


        Call tickerInfo = openApiService.tickerInfo("BTC");


5.3. Callback 정의

enqueue() 를 통해 Callback에 대해서 정의하자.


        tickerInfo.enqueue(new Callback() {
            @Override
            public void onResponse(Call call, Response response) {
                Toast.makeText(TestMainActivity.this, response.body().toString(), Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onFailure(Call call, Throwable t) {
                Toast.makeText(TestMainActivity.this, t.toString(), Toast.LENGTH_SHORT).show();
            }
        });


이상으로 간단하게 Retrofit 시식을 마칠까 한다.




Retrofit 로그 보는 법과 Proguard 설정에 대해서 추가한다.


6. 로그 보는 법

build.gradle에 아래와 같이 추가한다.


dependencies {
        compile 'com.squareup.okhttp3:logging-interceptor:3.9.1'
        ...
}


그리고 Retrofit 초기화 하는 부분에 아래와 같이 추가한다.


        HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
        interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
        OkHttpClient client = new OkHttpClient.Builder().addInterceptor(interceptor).build();

        Retrofit.Builder retrofitBuilder = new Retrofit.Builder().baseUrl(url);

        if(BuildConfig.DEBUG) {
            retrofitBuilder.client(client);
        }

        if(!isString) {
            retrofitBuilder.addConverterFactory(GsonConverterFactory.create());
        } else {
            retrofitBuilder.addConverterFactory(ScalarsConverterFactory.create());
        }
        Retrofit retrofit = retrofitBuilder.build();


기존과 비교했을 때 OkhttpClient 라는 놈을 Retrofit Builder에 추가하는 모습이 보인다.

개인적으로 디버그 모드일때만 로그를 보기 위해 BuildConfig.DEBUG 로 분기 처리를 하였다.

그리고 로그 수준은 아래와 같다.


public final class HttpLoggingInterceptor implements Interceptor {
   ...
  public enum Level {
    /** No logs. */
    NONE,
    /**
     * Logs request and response lines.
     *
     * 

Example: *

{@code
     * --> POST /greeting http/1.1 (3-byte body)
     *
     * <-- 200 OK (22ms, 6-byte body)
     * }
*/ BASIC, /** * Logs request and response lines and their respective headers. * *

Example: *

{@code
     * --> POST /greeting http/1.1
     * Host: example.com
     * Content-Type: plain/text
     * Content-Length: 3
     * --> END POST
     *
     * <-- 200 OK (22ms)
     * Content-Type: plain/text
     * Content-Length: 6
     * <-- END HTTP
     * }
*/ HEADERS, /** * Logs request and response lines and their respective headers and bodies (if present). * *

Example: *

{@code
     * --> POST /greeting http/1.1
     * Host: example.com
     * Content-Type: plain/text
     * Content-Length: 3
     *
     * Hi?
     * --> END POST
     *
     * <-- 200 OK (22ms)
     * Content-Type: plain/text
     * Content-Length: 6
     *
     * Hello!
     * <-- END HTTP
     * }
*/ BODY }

위 소스를 보면 로그 레벨은 NONE, BASIC, HEADERS, BODY 로 이루어져 있다. 필요에 따라 설정하면 된다.

- NONE : No logs.

- BASIC : Logs request and response lines.

- HEADERS : Logs request and response lines and their respective headers.

- BODY : Logs request and response lines and their respective headers and bodies (if present).


위와 같이 하였을 때 로그는 아래와 같이 떨어진다.


12-26 17:53:03.411 15500-15624/com.test.testblabla D/OkHttp: --> GET https://api.bithumb.com/public/ticker/BTC
12-26 17:53:03.411 15500-15624/com.test.testblabla D/OkHttp: --> END GET
12-26 17:53:04.101 15500-15624/com.test.testblabla D/OkHttp: <-- 200 https://api.bithumb.com/public/ticker/BTC (693ms)
12-26 17:53:04.101 15500-15624/com.test.testblabla D/OkHttp: date: Tue, 26 Dec 2017 08:53:04 GMT
12-26 17:53:04.101 15500-15624/com.test.testblabla D/OkHttp: content-type: application/json
12-26 17:53:04.101 15500-15624/com.test.testblabla D/OkHttp: set-cookie: __cfduid=dd24fcf80c27cf456c60e275644e40a0e1514278384; expires=Wed, 26-Dec-18 08:53:04 GMT; path=/; domain=.bithumb.com; HttpOnly
12-26 17:53:04.101 15500-15624/com.test.testblabla D/OkHttp: access-control-allow-origin: *
12-26 17:53:04.101 15500-15624/com.test.testblabla D/OkHttp: access-control-allow-methods: *
12-26 17:53:04.101 15500-15624/com.test.testblabla D/OkHttp: access-control-allow-headers: *
12-26 17:53:04.101 15500-15624/com.test.testblabla D/OkHttp: set-cookie: ci_session=a%3A5%3A%7Bs%3A10%3A%22session_id%22%3Bs%3A32%3A%22cf7e414ece7af81b8a35a0cdcaccd317%22%3Bs%3A10%3A%22ip_address%22%3Bs%3A12%3A%221.227.62.114%22%3Bs%3A10%3A%22user_agent%22%3Bs%3A12%3A%22okhttp%2F3.9.1%22%3Bs%3A13%3A%22last_activity%22%3Bi%3A1514278384%3Bs%3A9%3A%22user_data%22%3Bs%3A0%3A%22%22%3B%7D4ca3239efcb6f4f81c5c8703401ade3bbef4e9fd; expires=Tue, 26-Dec-2017 10:53:04 GMT; Max-Age=7200; path=/
12-26 17:53:04.101 15500-15624/com.test.testblabla D/OkHttp: server: cloudflare-nginx
12-26 17:53:04.101 15500-15624/com.test.testblabla D/OkHttp: cf-ray: 3d32cec0fef194b7-NRT
12-26 17:53:04.101 15500-15624/com.test.testblabla D/OkHttp: {"status":"0000","data":{"opening_price":"19157000","closing_price":"20632000","min_price":"18853000","max_price":"21400000","average_price":"19977707.8742","units_traded":"26050.76859352","volume_1day":"26050.76859352","volume_7day":"176662.05473862","buy_price":"20620000","sell_price":"20623000","date":"1514278384536"}}
12-26 17:53:04.101 15500-15624/com.test.testblabla D/OkHttp: <-- END HTTP (323-byte body)

참조링크1 : https://github.com/square/okhttp/tree/master/okhttp-logging-interceptor

참조링크2 : https://stackoverflow.com/questions/32514410/logging-with-retrofit-2


7. Progaurd 설정

앱을 실제 signed release apk 만들시 Progaurd 사용하는데, 이때 Retrofit 사용시 아래와 같이 proguard.pro 파일에 추가해준다.


# Platform calls Class.forName on types which do not exist on Android to determine platform.
-dontnote retrofit2.Platform
# Platform used when running on Java 8 VMs. Will not be used at runtime.
-dontwarn retrofit2.Platform$Java8
# Retain generic type information for use by reflection by converters and adapters.
-keepattributes Signature
# Retain declared checked exceptions for use by a Proxy instance.
-keepattributes Exceptions


Retrofit 로그에서 문제가 될시 아래도 추가해 보자.


-dontwarn okhttp3.**
-dontwarn okio.**
-dontwarn javax.annotation.**
# A resource is loaded with a relative path so the package of this class must be preserved.
-keepnames class okhttp3.internal.publicsuffix.PublicSuffixDatabase

참조링크1 : http://square.github.io/retrofit/

참조링크2 : https://github.com/square/okhttp

+ Recent posts