일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- 플레이스토어 앱 게시 문제
- 안드로이드스튜디오
- 안드로이드 http
- android api
- android studio
- 안드로이드 스튜디오
- 달력 만들기
- Callback
- urlconnection
- 비동기
- 앱개발
- Bottom sheet
- 앱 출시
- Exposed Drop-Down Menu
- 안드로이드 api
- Retrofit
- 레트로핏
- Kotlin
- 공유 기능
- Dialog
- 플레이 콘솔 프로덕션
- Today
- Total
Strong 감자의 공부
안드로이드 api 통신_callback함수 본문
api 통신 시 callback 함수와 viewModelScope를 사용했다.(callback은 비동기/ 동기로 사용가능하며, callback을 호출하는 함수에 따라 callback이 비동기/동기 중 어떻게 작동할지 결정된다.)
- 동기 콜백: 호출하는 함수가 콜백을 호출한 뒤, 콜백 작업이 완료될 때까지 호출하는 함수가 대기합니다.
- 비동기 콜백: 호출하는 함수가 콜백을 호출한 뒤 대기하지 않고 바로 종료됩니다.
위에 글만 읽으면 이해가 안가니 예제를 가져오겠슴다.
1. 동기식 callback예제
람다로 구성된 아래 코드를 간단히 설명하자면
executeCallback {} 안에 있는 코드가(= println("Inside callback") ) callback() 호출 시 실행되는 문이다.
executeCallback(callback: () -> Unit)를 뜯어보자면
()는 함수의 매개변수, Unit은 함수 호출 후 반환값이 없음을 말한다.
println("Inside callback")은 단순 프린트 문이라 매개변수도, 반환값도 없다.
=>람다를 사용하지 않고 함수 작성할때도 리턴값 없이 프린트 문만 출력 한다면 반환값을 void로 하는것과 같다.
fun executeCallback(callback: () -> Unit) {
println("Before callback")
callback() // 콜백 호출
println("After callback")
}
fun main() {
executeCallback {
println("Inside callback") // 콜백의 본문 내용
}
}
// 결과
Before callback
Inside callback
After callback
혹시 매개변수랑 리턴값이 있을 때를 궁금해할 사람들을 위해 chat gpt에서 예시 긁어왔슴당.
input은 callback으로 전달되는 "kotlin"입니다.
fun executeCallback(callback: (String) -> String) {
println("Before callback")
val result: String = callback("Kotlin") // 콜백 함수의 반환값을 받음
println("Callback returned: $result") // 반환값 출력
}
fun main() {
executeCallback { input ->
println("Inside callback with input: $input") // 매개변수를(executeCallback에서 callback("kotlin")) 사용해 문자열 반환
"Hello, $input!" // 리턴값
}
}
// 결과
Before callback
Inside callback with input: Kotlin
Callback returned: Hello, Kotlin!
2. 비동기식 callback예제
우선 알아둬야 할건 네트워크 요청은 비동기이다. 그렇기 때문에 api 호출하는 함수를 일반함수로만 작성하면 안된다!!
아래는 내가 작성한 코드이다.
// fragment.kt 코드
private val viewModel: ChangeNickNameViewModel by viewModels()
...
binding.btnComplete.setOnClickListener {
viewModel.isDuplicationNickname(object : CallBackListener {
override fun isSuccess(result: Boolean) {
if (result) {
// 성공 시
} else {
// 실패 시
}
}
})
}
// viewModel.kt 코드
fun isDuplicationNickname(params: CallBackListener) {
viewModelScope.launch {
val response =
RetrofitManager.api.checkNicknameDuplication(nickname = nickname.value.toString())
if (response.isSuccessful) {
params.isSuccess(true)
} else {
params.isSuccess(false)
}
}
}
// interface.kt 코드
interface CallBackListener {
fun isSuccess(result: Boolean)
}
🔗 코드 작동 순서
fragment에서 btnComplete라는 버튼이 눌리면 viewModel.kt에 작성된 isDuplicationNickname함수가 호출된다.
호출 시 fragment에서 구체화한 CallBackListener 구현체(isSuccess)가 호출 함수( isDuplicationNickname )에 전달된다. 다시 fragment.kt로 반환되는거 아님!
여기서 의문점...!
✔️ 호출된 isDuplicationNickname은 네트워크 응답값을 기다렸다가 끝나나? ❌
- 해당 일반 함수는 그냥 끝난다. = 끝나니까 네트워크 응답값이 나중에 와도 못받음!
✔️ 호출된 isDuplicationNickname 함수가 종료되면 해담 함수 안의 params.isSuccess(true) or (false)은 어떻게 동작하는가?
- viewModelScope.launch로 코루틴을 시작하면, 이 코루틴은 백그라운드에서 네트워크 요청을 처리된다.
- isDuplicationNickname 함수는 종료되더라도 코루틴 내의 네트워크 작업은 계속 진행된다.
✔️ 만약 viewModelScope.launch와 같은 코루틴 스코프로 감싸지 않으면?
- 코루틴이 아닌 일반 함수로 동작하게 된다.
- 네트워크 요청이 실행되더라도 함수 자체는 결과를 기다리지 않고 그대로 종료된다.
TⓂ️ℹ️
처음 서버와 통신하는 기능을 구현할 때 callback 개념을 몰라 넘 막막했다...
코루틴 스코프같은 비동기 컨텍스트도 몰라 api 요청 시 함수 종료로 에러가 발생했는데 그 당시 나땜에 프젝 진행 안될까봐 발동동 구르며 전전긍긍 앓았다🥹🥹
해결하기위해 구글링하는 과정에서 많은 북마크를 날렸고 그때의 급급함이 북마크에 고스란히 남아있다..(북마크 언제 정리하지😑)
발에 불 떨어지면 어떻게든 하는 나..🫠
'앱개발 > StudyHub 앱 출시 회고' 카테고리의 다른 글
Retrofit 사용해보기 #1 (0) | 2024.12.30 |
---|---|
달력 만들기 (1) | 2024.12.30 |
앱 게시 문제_#심사는 끝났는데 플레이 스토어에 앱이 안보일 때 (0) | 2024.12.27 |
앱 출시 회고_intro (0) | 2024.12.26 |
api 응답 값 에러 시 확인 절차 (0) | 2023.09.21 |