2019. 10. 24. 20:25ㆍProgramming/Android
Volley에서 Retrofit2로 HTTP 라이브러리의 변경을 결정하기까지.
2019년 11월부터 targetSDKVersion이 28 미만인 앱은 업데이트가 불가능하도록 정책이 변경됐다. targetSDKVersion이 28로 변경되면, Apache의 HTTPClient 지원이 중단된다. 여기까지는 별 생각이 없었는데, 실제로 targetSDKVersion을 28로 변경해보니 뭔가 이상하다. Volley를 사용하여 HTTP 통신을 하는 코드들이 오작동하기 시작한다. Android 5.1
에서 HttpClient
가 Deprecated되면서, HTTPClient
에 의존하는 Volley
도 사실상 Deprecated됐기 때문이다. 이에 대한 내용은 Android 통신 라이브러리의 역사를 되돌아본다, Pluu Dev 혹은 Androidの通信ライブラリの歴史を振り返る, Qiita를 참조하도록 하자. Retrofit2에 대해 조사할 때 Qiita에서 꽤 인상깊었던 글이었는데, Pluu님이 잘 번역해주셨다.
<uses-library android:name="org.apache.http.legacy" android:required="false"/>
위의 코드를
AndroidManifest.xml
의Application
항목 하위에 추가하면,Apache
의HTTPClient
를 계속 사용할 수 있다. 즉,targetSDKVersion
을 올리더라도, 계속해서Volley
를 사용할 수 있다는 얘기다.AndroidManifest.xml
에 위와 같은 설정을 추가하면, Apache의HTTPClient
를 계속 사용할수는 있다. 다만 기존에 Android SDK에 포함되어있는Apache HttpComponents
의HttpClient
의 경우 널리 알려진 버그가 있었으며, 하위 호환성 때문에 Apache HttpClient의 최신 버전을 따라가지 않고 있다. 이 내용에 대해서는, Android의 HTTP 클라이언트 라이브러리, NAVER D2 글을 참조하도록 하자.
위에서 열거한 문제를 차치하더라도, 여전히 Deprecated된 Volley
를 계속해서 가져가는 것이 옳은지는 의문이었다. 또한 Android 6.0
에서부터 Apache HTTPClient를 지원하지 않다가, Android 9
에서부터는 완전히 삭제되고 AndroidManifest.xml
에 옵션처럼 지정해야만 쓸 수 있게 됐다. 그렇다면 다음 버전에도 이 옵션을 사용할 수 있을까? 아무도 장담할 수 없었기에, 자사에서 Volley
를 사용하여 HTTP 통신을 하던 코드를 Retrofit2로 대체하기는 작업을 시작했다.
Retrofit2에 대하여.
위에서 언급한 Android 통신 라이브러리의 역사를 되돌아본다, Pluu Dev/Androidの通信ライブラリの歴史を振り返る, Qiita 페이지를 다시 읽어보면 선택지가 좀 있었는데, 사전지식이 많지는 않았기 때문에 검색으로 판단할수밖에 없었다. 그 결과 검색해봤을 때 자료양이 비교적 많았던 Retrofit2를 선택하게 됐다. Android 개발에 대해서 문제에 부딪혔을 때, 의존할 수 있는 것은 검색밖에 없었기 때문이다.
물론 사전에 고려해야 할 사항이 더 있었다. 임베디드 장비와 통신할 시 장비에서 Basic/Digest 인증방식을 선택할 수 있다는 점이라거나, 얼마나 모듈화를 통해 생산성을 극대화할 수 있는지라던가, 기타 등등... 물론 당시에는 전혀 고려하지 못했던 것들이다. 이래서 경험이 중요한 것인가싶다.
Retrofit2을 적용하면서.
Retrofit2 웹 사이트/Retrofit2 웹 사이트(KR)에 대부분의 내용이 정리되어있는데, 잘 눈에 들어오지 않아서 검색을 통해 내용을 확인해야했다. 문서를 보고 기능을 구현한 다음에 다시 웹 사이트를 확인해보니, 대충 눈에 들어오기 시작하는데... 뭔가 아쉬운 것은 어쩔 수 없었다. Retrofit2 웹 사이트에는 JAR파일 링크만 있어서 처음엔 불만이었는데, 사실 Library Dependency
에서 검색을 통해 필요한 라이브러리를 import할 수 있다는 걸 깨닫고 그냥 내가 무지했었구나 싶었다.
Kotlin
을 사용하고싶었는데, Retrofit2 웹 사이트에는 Kotlin
으로 구현된 코드가 없던 것도 조금 아쉬웠다. 이러한 문제 때문인지 아니면 요즘에는 기술블로그가 많아졌기 때문인지, Kotlin
을 사용해서 Retrofit2
라이브러리를 사용하는 예제코드를 찾는 일은 어렵지 않았다. 실제로 Kotlin Retrofit2
로 검색하면, 검색 결과가 한가득 나와서 금방금방 처리할 수 있었다.
보통 Retrofit2를 사용하는 예제들은 HTTP API의 호출결과를 JSON
형태로 주는 경우가 많다보니, GSON
라이브러리를 사용하여 리턴값을 파싱하고 있었다. 컨버터는 별도 라이브러리여서 그런지 Retrofit2 웹 사이트에서는 매우 간략하게 기술하고 지나간다. 나의 경우에는 호출하는 API에 따라서 JSON을 파싱하는 경우도 있었지만, 일반적으로는 STRING을 반환해주는 경우가 있었기 때문에 Scalars
라이브러리를 사용해야 했다. Scalars
라이브러리에 대한 내용은 나중에 업데이트 된 내용인지, Retrofit2 웹 사이트(KR)에는 나와있지 않았다. 하지만 역시나 Retrofit2 String response
등으로 구글링(...)하게되면 결과물이 한가득 나온다.
Retrofit2의 인증에 대하여.
개인적으로 올해는 Digest 인증 방식과 엮이는 일이 상당히 많았는데, 요즘에는 잘 사용되지 않는 방식인지 Retrofit2 자체적으로 지원하지는 않는 듯 했다. 사실 JavaScript로 구현했던 걸 또 다시 Kotlin으로 구현하는 것도 썩 내키지는 않아서, 전임자가 Volley로 짜놓은 코드를 갖다쓰려고 했다. 하지만 HTTPClient를 사용해서 Authorization 필드를 생성하고 있는 게 아닌가. 딱히 어려운 코드는 아니어서, 여차하면 유지보수할 요량으로 새로 작성했다. 시간이 되면 Basic/Digest 인증 모듈을 따로 작성해놓던가 해야겠다.
처음에는 Interceptor에 대한 개념을 파악하지 못해서 HTTP Status가 401로 왔을 때 다시 한 번 Request를 날리는 코드를 작성했지만, Interceptor를 사용하도록 코드를 갈아엎고나니 상당히 편리했다. OKHttp.Interceptors
에 대한 내용은 OKHttp.Interceptors를 참조하도록 하자. 아마 Retrofit2보다 OkHttp에서 제공해주는 개념이다보니 Retrofit2 페이지에는 Headers that need to be added to every request can be specified using an OkHttp interceptor.
한 줄로 지나간게 아닌가 싶었다.
OKHttp.Interceptor
를 이용하여 Basic/Digest 인증을 구현한 내용은 다른 글로 작성할 예정이다.
마무리
사실 이제부터가 시작이다. 어플리케이션에서 기존에 Volley를 이용하여 통신하던 코드를 파악하고, 해당 코드를 모두 Retrofit2
를 사용하여 통신하도록 수정하는 작업이 남은 셈이다. 글을 요약해서 정리하면 다음과 같다.
- 어플리케이션에서 사용하고 있던 HTTP Library를 Volley에서 Retrofit2로 변경하는 작업을 진행하기 시작했다.
- Retrofit2 홈페이지는 예제가 없어서 곤란했는데, 구글링해보니까 예제가 한가득 나와서 다행이었다.
- 또 Digest 인증방식을 구현했다. 이번엔 Kotlin으로.
- Basic/Digest 인증방식을 구현해보니, OKHttp의 Interceptors가 정말 좋더라.
뭔가 꽤 많이 적었는데 단 네 줄로 요약되는 내용이라니.
다음부터는 글을 좀 짧게 줄이는 습관을 들여야겠다. ' ㅅ'
'Programming > Android' 카테고리의 다른 글
Retrofit2를 이용해서 서버로부터 Content-type이 image/jpeg로 이미지를 받아 Bitmap 객체로 처리하기 (0) | 2019.11.05 |
---|---|
Kotlin <-> Java 클래스를 서로 참조 못할 때(Can not find symbol) (0) | 2019.11.03 |
3일에 걸친 리펙토링을 하고나서, 코드를 잘 작성하는 법에 대해 생각해봤다. (2) | 2019.09.15 |
[NDK] Colorspace Conversion 관련 삽질기 (0) | 2019.07.04 |
[Android] Thread와 BlockingQueue에 대한 삽질기록 (0) | 2019.06.28 |