코딩기록
[안드로이드 스튜디오] retrofit2 동기처리 본문
1. 문제발생
농구장 위치 공유 앱 개발 중, 다음과 같이 전역변수의 값을 retrofit을 통해 설정하려고 하였으나 전역변수에 값이 저장되지 않았다.
var hoop = intent.getSerializableExtra("hoop") as Hoop
val retrofit = Retrofit.Builder().baseUrl(BuildConfig.API_URL)
.addConverterFactory(GsonConverterFactory.create()).build()
val service = retrofit.create(RetrofitService::class.java)
service.getHoop(hoop.id)
.enqueue(object : Callback<ResponseDto<Hoop>> {
override fun onResponse(
call: Call<ResponseDto<Hoop>>,
response: Response<ResponseDto<Hoop>>
) {
hoop = response.body()!!.data
}
override fun onFailure(call: Call<ResponseDto<Hoop>>, t: Throwable) {
Toast.makeText(
this@PopupActivity,
"농구장 불러오기에 실패했습니다. 잠시 후 다시 시도해 주세요.",
Toast.LENGTH_LONG
).show()
}
})
2. 원인
원인을 확인해 보니 사용하고 있던 retrofit의 <.enqueue> 메서드는 비동기 방식으로 정보를 가져오기 때문에 발생한 문제였다. 즉, api로 정보를 다 가져오기 전에 그 다음 코드가 실행되어 버린 것이다.
동기 방식의 <.execute>를 사용하면 정보가 저장될 수 있을 것이다.
3. 트러블슈팅
그러나 .execute를 사용했더니 NetworkOnMainThreadException가 발생했다.
원인은 Network API를 MainActivity에서 직접 호출했기 때문이다. 이것을 금지해 놓은 이유를 확인해 보니 MainActivity에서 Network관련 작업을 직접 실행할 경우 MainThread가 멈추는 현상이 발생할 수 있기 때문에 이를 금지시켜 놓은 것이었다.
-> 다음과 같이 새로운 쓰레드를 구동시킴으로써 .execute 메서드를 사용할 수 있었다.
Thread {
hoop = service.getHoop(hoop.id).execute().body()!!.data
binding.name.text = hoop.name
binding.hoopCount.text = if (hoop.hoopCount == 0) "(정보없음)" else hoop.hoopCount.toString()
binding.floorType.text = hoop.floorType.krName
binding.light.text = hoop.light.krName
binding.freeState.text = hoop.freeState.krName
binding.standardState.text = hoop.standardState.krName
binding.commentBtn.text = "추가정보 : 이 농구장의 댓글 " + hoop.commentCount + "개"
// 댓글
binding.commentBtn.setOnClickListener {
this.finish()
val intent = Intent(this@PopupActivity, CommentPopupActivity::class.java)
intent.putExtra("hoop", hoop)
startActivity(intent)
}
// 업데이트
binding.updateBtn.setOnClickListener {
this.finish()
val intent = Intent(this@PopupActivity, UpdatePopupActivity::class.java)
intent.putExtra("hoop", hoop)
startActivity(intent)
}
// 신고
binding.reportBtn.setOnClickListener {
this.finish()
val intent = Intent(this@PopupActivity, ReportPopupActivity::class.java)
intent.putExtra("hoop", hoop)
startActivity(intent)
}
}.start()
'백엔드 > Kotlin' 카테고리의 다른 글
코틀린 물음표(?)와 느낌표(!) 차이 (0) | 2024.05.19 |
---|