728x90
commit message : Establish communication with API by callback method using okhttp, okhttp interceptor, retrofit2
경로 : app/build.gradle
//okhttp and okhttp interceotor
def okhttp_version = "4.9.0"
implementation "com.squareup.okhttp3:okhttp:$okhttp_version"
implementation "com.squareup.okhttp3:logging-interceptor:$okhttp_version"
//retrofit2
def retrofit_version = "2.9.0"
implementation "com.squareup.retrofit2:retrofit:$retrofit_version"
implementation "com.squareup.retrofit2:converter-gson:$retrofit_version"
경로 : app/src/main/java/com/example/lifehelper/DomainLayer/repository/Retrofit_Service.kt
interface Retrofit_Service {
@GET(API.SEARCH_WEATHER)
fun search_weather(
@Query("lat") lat : String,
@Query("lon") lon : String) : Call<JsonElement>
}
경로 : app/src/main/java/com/example/lifehelper/DataLayer/Client/RetrofitClient.kt
object RetrofitClient {
fun getApiClient(baseUrl: String) : Retrofit {
return Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create())
.baseUrl(baseUrl)
// 위에서 설정한 client로 retrofit client를 설정한다.
.client(getOkHttpClient())
.build()
}
fun getOkHttpClient() : OkHttpClient {
Log.d(Constants.TAG, "${this@RetrofitClient::class.java.simpleName}" +
"getOkHttpClient() called")
val client = OkHttpClient.Builder()
val baseParmsInterceptor = object : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
Log.d(Constants.TAG, "${this@RetrofitClient::class.java.simpleName}" +
"intercept() / chain : $chain")
/**
* 1) 공통 파라미터 장착
*/
val originalRequest = chain.request()
val addClientIdUrl = originalRequest .url.newBuilder()
.addQueryParameter("appid", API.API_ID)
.addQueryParameter("lang", API.LANGUAGE)
.build()
Log.d(Constants.TAG, "${this@RetrofitClient::class.java.simpleName}" +
"intercept() / addClicentUrl : $addClientIdUrl")
val finalRequest = originalRequest.newBuilder()
.url(addClientIdUrl)
.method(originalRequest.method, originalRequest.body)
.build()
/**
* 2) 서버로 부터 응답받기
*/
val response = chain.proceed(finalRequest) //오리지날 요청으로 변경하면 401에러 문제없이 출력됨
/*
if(response.code != 200){
Handler(Looper.getMainLooper()).post {
//Handler() - android.os, 백그라운드 스레드에서 작업 중, ui 스레드에서 실행하도록 변경
//Toast.makeText(App.instance, "${response.code} 에러 입니다.", Toast.LENGTH_SHORT).show()
}
}
*/
return response
}
}
client.addInterceptor(baseParmsInterceptor)
// 위에서 생성한 기본 파라미터 인터셉터를 okhttp clent에 추가
return client.build()
}
}
2) 서버로 부터 응답을 받고 HTTP 상태 코드에 따라 처리를 할 수 있지만, UI 조작은 다른 곳에서 처리하는게 좋을 것 같아 일단은 주석 처리
경로 : app/src/main/java/com/example/lifehelper/DomainLayer/usecase/RetrofitManager.kt
class RetrofitManager {
companion object {
val instance = RetrofitManager()
}
private val retrofitService: Retrofit_Service? =
RetrofitClient.getApiClient(API.BASE_URL).create(Retrofit_Service::class.java)
fun searchWeather(lat: String?, lon: String?, completion: (RESPONSE_STATE, JsonElement?) -> Unit) {
Log.d(Constants.TAG, "${this::class.simpleName} " +
"searchWeater() called")
val lat = lat.let { it } ?: ""
val lon = lon.let { it } ?: ""
retrofitService?.search_weather(lat, lon)?.clone()?.enqueue(object : retrofit2.Callback<JsonElement> {
override fun onResponse(call: Call<JsonElement>, response: Response<JsonElement>) {
Log.d(Constants.TAG, "${this@RetrofitManager::class.simpleName} " +
"onResponse() called : response.raw(): ${response.raw()}")
Log.d(Constants.TAG, "${this@RetrofitManager::class.simpleName} " +
"onResponse() called : response.body(): ${response.body()}")
Log.d(Constants.TAG, "${this@RetrofitManager::class.simpleName} " +
"onResponse() called : response.code(): ${response.code()}")
var weatherData: WeatherData? = null
when (response.code()) {
200 -> {
response.body?.apply {
val body = this.asJsonObject
val weather = body.getAsJsonArray("weather")
weather.forEach { weatherItem ->
val weatherObject = weatherItem.asJsonObject
val main = weatherObject.get("main").asString
Log.d(Constants.TAG, "${this@WeatherViewModel::class.java.simpleName} " +
"main : $main")
weatherData = weatherData(
main = main
)
}
}
weatherData?.let { completion(RESPONSE_STATE.OK, it) }
}
}
}
override fun onFailure(call: Call<JsonElement>, t: Throwable) {
Log.d(Constants.TAG, "${this@RetrofitManager::class.java.simpleName} " +
"onFailure() called : ${t}")
completion(RESPONSE_STATE.FAIL, null)
}
})
}
}
경로 : app/src/main/java/com/example/lifehelper/DomainLayer/model/WeatherData.kt
data class WeatherData(
var main : String?
//var description : String?,
//var wind_speed : String?,
//var cloud : String?,
//var rain_1h : String?,
//var snow_1h : String?
)
응답을 받은 후 파싱한 결과가 제대로 출력되는지만 확인하기 위해서 main만 사용한 상태
경로 : app/src/main/java/com/example/lifehelper/PresentationLayer/Fragment/WeatherFragment.kt
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
RetrofitManager.instance.searchWeather("37.5683", "126.9778") {
responseState, weatherData ->
when(responseState){
RESPONSE_STATE.OK -> {
Log.d(Constants.TAG, "HomeActivity api 호출 성공 ")
}
RESPONSE_STATE.FAIL -> {
Log.d(Constants.TAG, "HomeActivity api 호출 실패")
}
RESPONSE_STATE.NONE -> {
Log.d(Constants.TAG, "HomeActivity api 결과 없음 ")
}
}
}
}
}
'Project > Lifehelper' 카테고리의 다른 글
화면 캡처와 공유 (Bitmap, PixelCopy, File, FileOutputStream, FileProvider, Intent) (0) | 2021.05.09 |
---|---|
Branch : 06_FusedLocationProviderClient (0) | 2021.03.03 |
Branch : 05_checkPermission (0) | 2021.03.03 |
Branch : 01_uiDesign (Navigation Component / BottomNavigation View) (0) | 2021.02.26 |
Branch : 01_uiDesign (Localization / Ripple Effect) (0) | 2021.02.26 |