안드로이드 개발 팁 블로그

retrofit 1.9 -> 2.0, okhttp2 -> okhttp3 라이브러리 변경 삽질기. feat.Fresco 본문

Android Tip

retrofit 1.9 -> 2.0, okhttp2 -> okhttp3 라이브러리 변경 삽질기. feat.Fresco

tiii 2016.01.15 19:33



앱에서 네트워크 통신을 하면 가끔 Host를 찾을 수 없다라는 에러와 함께 API 호출이 되지 않는 문제가 있었다.
이리저리 손을 봐도 도통 모르겠더라. 
그러다가 문뜩 통신 라이브러리를 업데이트 해볼까? 혹시 버그 픽스가 됐을지도 모르잖아?..라는 생각에 업데이트를 감행하였다.
기존에 사용하던 라이브러리의 버전은 아래와 같다.
com.squareup.okhttp:okhttp:2.4.0
com.squareup.retrofit:retrofit:1.9.0

그리고 변경할 라이브러리의 버전은
com.squareup.okhttp3:okhttp:3.0.1
com.squareup.retrofit2:retrofit:2.0.0-beta3

Retrofit이 1에서 2로 업데이트되면서 많은 부분이 변경되었다는 것은 이미 알고 있었기에 다른 블로그의 포스팅을 참고하여 진행되었다.
(Retrofit 1.9에서 2.0으로 업데이트하기) 단순하게 몇개만 바뀐 줄 알았는데 아니였다. 변경한 작업기를 정리하여 올려 본다.


1.Retrofit API인터페이스 선언 부분 변경

기존

1
2
3
4
5
Interface = new RestAdapter.Builder()
                .setEndpoint(DIRECTFOLDER_SERVER)
                .setClient(new OkClient(client))
                .setLogLevel(RestAdapter.LogLevel.FULL)
                .build().create(df_Interface.class);
cs

변경 후

1
2
3
4
5
6
Interface = new Retrofit.Builder()
             .baseUrl(DIRECTFOLDER_SERVER)
             .client(client)
             .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
             .addConverterFactory(GsonConverterFactory.create())
             .build().create(df_Interface.class);
cs

함수명들이 직관적으로 완전히 완전 바꼈다.
API인터페이스의 호출 API 주소 선언 시 "/"가 빠졌다 따라서 api의 서버주소를 적을 때 마지막에 "/"를 붙이도록 변경 되었다.
@POST("/login") 이였다면 @POST("login")으로 바꼈다.
기존주소가 "http://google.com" 이였다면 바뀐 주소는 "http://google.com/"이다.

그리고 API Call을 할 때 Rx를 사용하여 결과 값을 리턴 받고 있었는데 1.9에서 바로 사용할 수 있었으나
2.0으로 바뀌면서 별도의 확장 라이브러리로 빼버렸다.
디펜던시에 com.squareup.retrofit:adapter-rxjava:2.0.0-beta3을 추가하고 
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())을 추가해야 Observable 콜백을 정상적으로 받을 수 있다.

기본 Json파서가 없어졌다. 1.9에서 Gson이 기본 Json파서 였는데 역시 확장 라이브러리로 뺐다.
디펜던시에 com.google.code.gson:gson:2.5을 추가하고
.addConverterFactory(GsonConverterFactory.create())을 추가해야 Gson라이브러리를 이용한 Json파싱이 가능하다.

마지막으로 2.0에서는 Logging선언을 Retrofit에서 할 수 없게 되었다.


2.OkHttpClient 선언 부분의 변화

Okhttp 만 바꾸고 싶었는데...retrofit1이 Okhttp3를 지원하지 않기 때문에 둘 다 바꾸다보니 일이 커졌다.ㅜㅜ
물론 제이크 형님의 https://github.com/JakeWharton/retrofit1-okhttp3-client 도 있으니 Okhttp라이브러리만 바꾸실 분은 참고하시라.

기존

1
2
3
4
5
6
7
8
client = configureClient(new OkHttpClient());
client.setConnectTimeout(CONNECT_TIMEOUT, TimeUnit.SECONDS);
client.setWriteTimeout(WRITE_TIMEOUT, TimeUnit.SECONDS);
client.setReadTimeout(READ_TIMEOUT, TimeUnit.SECONDS);
client.setCookieHandler(new MyCookieManager());
client.interceptors().add(new df_AddCookiesInterceptor());
client.interceptors().add(new df_ReceivedCookiesInterceptor());
 
cs

변경 후

1
2
HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor();
httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
cs(

1
2
3
4
5
6
7
8
9
client = configureClient(new OkHttpClient().newBuilder())
            .connectTimeout(CONNECT_TIMEOUT, TimeUnit.SECONDS)
            .writeTimeout(WRITE_TIMEOUT, TimeUnit.SECONDS)
            .readTimeout(READ_TIMEOUT, TimeUnit.SECONDS)
            .addInterceptor(new df_AddCookiesInterceptor())
            .addInterceptor(new df_ReceivedCookiesInterceptor())
            .addInterceptor(httpLoggingInterceptor)
            .cookieJar(new JavaNetCookieJar(new MyCookieManager()))
            .build();
cs

코드체이닝 빌더 방식으로 변경 되었다.다른 부분은 어려운 부분이 없었으나 CookieHander를 Set하는 부분이 완전히 변경되었다.
JavaNetCookieJar를 사용하기 위해 디펜던시에 com.squareup.okhttp3:okhttp-urlconnection:3.0.1 을 추가하였다.(뭐야..계속 늘어나..) 그리고 위에서 설명했던 Logging 부분을 이 곳에서 설정 할 수 있는데 디펜던시에 com.squareup.okhttp3:logging-interceptor:3.0.1을 추가하고 .addInterceptor(httpLoggingInterceptor) 이와 같이 인터 셉터를 추가하면 기존과 동일하기 로깅이 가능하다. 3.https handshake 에러 해결. 인증서를 무시하고 통과 되도록 변경하였다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
 public static OkHttpClient.Builder configureClient(final OkHttpClient.Builder builder) {
        final TrustManager[] certs = new TrustManager[]{new X509TrustManager() {
 
            @Override
            public X509Certificate[] getAcceptedIssuers() {
                return null;
            }
 
            @Override
            public void checkServerTrusted(final X509Certificate[] chain,
                                           final String authType) throws CertificateException {
            }
 
            @Override
            public void checkClientTrusted(final X509Certificate[] chain,
                                           final String authType) throws CertificateException {
            }
        }};
 
        SSLContext ctx = null;
        try {
            ctx = SSLContext.getInstance("TLS");
            ctx.init(null, certs, new SecureRandom());
        } catch (final java.security.GeneralSecurityException ex) {
        }
 
        try {
            final HostnameVerifier hostnameVerifier = new HostnameVerifier() {
                @Override
                public boolean verify(final String hostname, final SSLSession session) {
                    return true;
                }
            };
            builder.sslSocketFactory(ctx.getSocketFactory()).hostnameVerifier(hostnameVerifier);
        } catch (final Exception e) {
        }
 
        return builder;
    }
cs


4.fresco가 말썽이네. 마지막으로 본인이 사용하고 있던 이미지프로세싱 라이브러리인 fresco가 okhttp3를 지원하지 않았다. -_ㅠ (com.facebook.fresco:imagepipeline-okhttp:0.8.1 기준) 디펜던시에서 해당 라이브러리를 주석 처리하고 결국 okhttp3용으로 커스텀하여 다시 만들었다. 해당 소스는 gitst에 올려 두었다.





0 Comments
댓글쓰기 폼