이 글은 기존 운영했던 WordPress 블로그인 PyxisPub: Development Life (pyxispub.uzuki.live) 에서 가져온 글 입니다. 모든 글을 가져오지는 않으며, 작성 시점과 현재 시점에는 차이가 많이 존재합니다.
작성 시점: 2019-05-30
adibfara/WatchTower(https://github.com/adibfara/WatchTower)는 브라우저 내 에서 OKHttp으로 인한 통신에 대한 요청 / 결과 데이터 및 헤더 등을 볼 수 있는 라이브러리로, 2019년 5월 24일에 첫 버전이 릴리즈된 라이브러리이다.
지금까지 OKHttp으로 인한 통신을 앱에서 검출하려면 주로 facebook/stetho(https://facebook.github.io/stetho/) 를 사용했으나, stetho의 기반은 Chrome developer tools에 작동한다는 점에서 이 WatchTower는 그러한 제약을 가지지 않고, 앱 내에서 NanoHTTPd를 사용하여 웹 서버를 열고 자료를 볼 수 있게 하는 것에 큰 차이점을 가진다.
또한 차후 확장하여 액티비티 내에서 볼 수 있게 하는 점도 가능하니, 기능은 Stetho에 비해 매우 빈약하지만 (Stetho가 네트워크 인터셉터 외에도 뷰 구조나 덤프 등을 제공하기 때문에) 네트워크 인터셉트 기능으로 한정하면 WatchTower가 더 이점을 가진다고 볼 수 있다.
당연하게도 Retrofit 또한 OKHttp가 기반이므로 Retrofit를 사용해도 위 기능을 전부 활용할 수 있다.
따라서 이 글에서는 기본적인 WatchTower의 사용법을 소개한다.
모듈의 gradle에 아래 종속성을 추가한다.
implementation 'com.snakyapps.watchtower:core:1.0.0'
debugImplementation 'com.snakyapps.watchtower:interceptor-okhttp:1.0.0'
releaseImplementation 'com.snakyapps.watchtower:interceptor-okhttp-no-op:1.0.0'
debugImplementation, releaseImplementation으로 나눠지는데 이는 디버그 빌드에서만 해당 행동을 할 수 있게 종속성 분야에서 강제하는 것이다. 따라서 별도로 BuildConfig.DEBUG로 판단할 필요가 없어진다.
1.0.0 문서에 따르면, 안드로이드 환경에서는 Service에서 WatchTower를 시작하는 것이 권장된다고 되어있어, Service 객체를 생성한다.
class WatchTowerService : Service() {
override fun onBind(intent: Intent?): IBinder? {
return null
}
override fun onCreate() {
super.onCreate()
val port = Config.confg.watchTowerPort
WatchTower.start(WebWatchTowerObserver(port = port))
Timber.d("WatchTower is started. URL: http://localhost:$port")
}
override fun onDestroy() {
super.onDestroy()
WatchTower.shutDown()
}
}
<service
android:name=".module.watch.WatchTowerService"
android:enabled="true" />
위와 같이 작성하고 Manifest에 작성하였으면, 그 다음에는 OKHttp를 설정할 때에 Interceptor를 추가하면 된다.
현재 구축된 기반의 경우 Dagger의 Multibinding 기능을 이용하여 Set<Interceptor>
- LoggingInterceptor
순서로 추가하게 되어 있으므로, LoggingInterceptor
뒤에 WatchTower 자체의 Interceptor를 추가한다.
@Provides
fun provideClient(interceptors: Set<@JvmSuppressWildcards Interceptor>,
@Named("loginterceptor") logsInterceptor: Interceptor): OkHttpClient {
val builder = OkHttpClient().newBuilder()
builder.readTimeout(Config.config.timeout.toLong(), TimeUnit.MILLISECONDS)
builder.connectTimeout(Config.config.connectTimeout.toLong(), TimeUnit.MILLISECONDS)
builder.retryOnConnectionFailure(Config.config.retryOnConnectionFailure)
if (interceptors.isNotEmpty()) {
interceptors.forEach {
builder.addInterceptor(it)
}
}
if (!Config.config.notUseLogInterceptor) {
builder.addInterceptor(logsInterceptor)
}
if (Config.config.useWatchTower) {
builder.addInterceptor(WatchTowerInterceptor())
}
return builder.build()
}
마지막으로 Activity 에서 서비스를 시작하거나 중지하면 작동하게 된다.
이제, 앱을 빌드하게 되면 기기의 브라우저에서는 http://localhost:8085 를, PC에서는 http://기기의 로컬 주소:8085 를 입력하면 접속이 되고, OKHttp로 통해 통신이 진행될 경우 맨 위의 사진처럼 로그가 나오게 된다. 기기의 로컬 주소는 기기에서 https://www.whatismybrowser.com/detect/what-is-my-local-ip-address 에 접속하면 나온다.
간단한 사용법을 가지면서도, 편리한 사용법을 가져서 누구나 쉽게 적용할 수 있다는 포인트가 제일 강점이다. 구현하는 데에도 큰 시간이 들어가지 않으므로 적용해서 사용하면 큰 편리함을 얻을 수 있을 것 같다.