응답용 data class
- @SerializedName
- response json의 key값과 변수명이 다를 경우만 괄호 안에 문자를 입력해주면 된다.
- api의 key 값이 스네이크 케이스일 경우에 써주는 것이 좋다.
data class DustResponse(
@SerializedName("body")
val dustBody: DustBody,
@SerializedName("header")
val dustHeader: DustHeader
)
data class DustBody(
val totalCount: Int,
@SerializedName("items")
val dustItem: MutableList<DustItem>?,
val pageNo: Int,
val numOfRows: Int
)
HTTP 통신을 위한 인터페이스
- 각 HTTP 메소드에 맞게 어노테이션을 달아주고 baseURL 뒤에 이어지는 값을 파라미터로 넣어준다.
- api통신은 메인 스레드(lifecycle)에서 동작하면 안되기 때문에 suspend를 추가해줘야 한다.
interface NetWorkInterface {
@GET("getCtprvnRltmMesureDnsty") //시도별 실시간 측정정보 조회 주소
suspend fun getDust(@QueryMap param: HashMap<String, String>): Dust
}
HTTP Client 객체
object NetWorkClient {
private const val DUST_BASE_URL = "https://apis.data.go.kr/B552584/ArpltnInforInqireSvc/"
private fun createOkHttpClient(): OkHttpClient {
val interceptor = HttpLoggingInterceptor()
if (BuildConfig.DEBUG)
interceptor.level = HttpLoggingInterceptor.Level.BODY
else
interceptor.level = HttpLoggingInterceptor.Level.NONE
return OkHttpClient.Builder()
.connectTimeout(20, TimeUnit.SECONDS)
.readTimeout(20, TimeUnit.SECONDS)
.writeTimeout(20, TimeUnit.SECONDS)
.addNetworkInterceptor(interceptor)
.build()
}
private val dustRetrofit = Retrofit.Builder()
.baseUrl(DUST_BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.client(
createOkHttpClient()
).build()
// Retrofit 객체에 HTTP 요청을 담은 인터페이스를 넣어준다.
val dustNetWork: NetWorkInterface = dustRetrofit.create(NetWorkInterface::class.java)
}
Activity
- main 스레드에서는 HTTP통신하는 작업을 할 수 없다.
- 화면을 구성하는 도중에 통신에 문제가 생기면 앱이 멈춰 버리니까
- coroutine scope내에서 동작한다.
- 그 안에서 UI와 관련된 작업을 할 경우에는 `runOnUiThread` 안에서 작성해준다.
private fun communicateNetWork(param: HashMap<String, String>) = lifecycleScope.launch() {
// param에 넣어 보낸 요청에 대한 응답
val responseData = NetWorkClient.dustNetWork.getDust(param)
Log.d("Parsing Dust ::", responseData.toString())
val adapter = IconSpinnerAdapter(binding.spinnerViewGoo)
items = responseData.response.dustBody.dustItem!!
val goo = ArrayList<String>()
items.forEach {
Log.d("add Item :", it.stationName)
goo.add(it.stationName)
}
runOnUiThread {
binding.spinnerViewGoo.setItems(goo)
}
}
- api 통신에 필요한 값들을 map에 넣어서 요청해야 한다.
private fun setUpDustParameter(sido: String): HashMap<String, String> {
val authKey = "qhdzDnKy/PKGm9mro7LYY1VZsaqFfXfiCwZ+9Gugc/ZEXS4rwe5LkW/W7jNd5s23MYm7d6laZRGRveKF4EKHZQ=="
return hashMapOf(
"serviceKey" to authKey,
"returnType" to "json",
"numOfRows" to "100",
"pageNo" to "1",
"sidoName" to sido,
"ver" to "1.0"
)
}