어떻게 하면 네트워크 통신을 할 수 있는가?
백그라운드 쓰레드로 뒤에서 작업을 해야 함
-> 네트워크 통신을 백그라운드 쓰레드로 보내고
화면 반영을 UI 쓰레드로 바꿔줘야 함
Coroutine을 통해 어떻게 하면 쓰레드 번갈아가면서 네트워크 통신할 수 있는지
Coroutine?
코루틴이란
비동기 실행 코드를 간소화하는 설계 패턴
코루틴은 비동기적으로 실행되는 코드를 간소화하기 위해 Android에서 사용할 수 있는 동시 실행 설계 패턴입니다.
UI 쓰레드과 백그라운드 쓰레드를 우리가 지정해서 사용할 수도 있다는 편의성이 있다.
http를 사용하려면 먼저
build.gradle (:app) 파일에 두 가지를 작성해 주어야 한다.
implementation 'com.squareup.okhttp3:okhttp:4.9.0'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.2'
실습 수업에서는 couroutine 말고 gson을 사용해서 이렇게 작성하였다.
implementation 'com.squareup.okhttp3:okhttp:4.9.0'
implementation 'com.google.code.gson:gson:2.8.7'
sync를 통해 세팅해주어야 한다.
그리고 또 까먹지 말아야 할 세팅 !!
AndroidManifest.xml 파일에 INTERNET permission을 주어야 한다.
<uses-permission android:name="android.permission.INTERNET"/>
fun longTask() = CoroutineScope(Dispatchers.Default).async { // 비동기 방식
// network
}
Default로 지정하면 background 실행을 의미한다.
button.setOnClickListener {
CoroutineScope(Dispatchers.Main).launch(){ // 동기 방식
textView.text = longTask().await().toString()
}
}
이때 longTask()는 아까 함수로 따로 빼둔 background 실행!
http 통신을 할 함수를 만들어보자
여기부터는 센치한개발자 님의 "안드로이드 스튜디오 - 코틀린, 코루틴과 Http통신"에 나오는 코드대로 작성하였다.
fun getHtml(): String {
// 1. 클라이언트 만들기
val client = OkHttpClient.Builder().build()
// 2. 요청
val req = Request.Builder().url("https://www.google.com").build()
// 3. 응답
client.newCall(req).execute().use {
// response
response -> return if(response.body != null) {
response.body!!.string()
}
else {
"boody null"
}
}
- (호출을 통한) 응답
client newCall(req).execute() 또는 enqueue(Callback)
// execute가 동기, enqueue가 비동기
그리고 이걸 background로 지정한 coroutine default 부분에 넣는다.
fun coroutine() {
CoroutineScope(Dispatchers.Main).launch {
val html = CoroutineScope(Dispatchers.Default).async {
// network
getHtml() // main thread 부분에 적으면 오류가 난다.
}.await()
val mTextMain = findViewById<TextView>(R.id.mTextMain)
mTextMain.text = html.toString()
// main thread
}
}
실행하면 이렇게 네트워크 데이터를 가지고 온다.
이번에는 enqueue() 비동기 방식을 사용하여 응답하는 경우다.
fun getHtmlStr() {
// 1. 클라이언트 만들기
val client = OkHttpClient.Builder().build()
// 2. 요청
val req = Request.Builder().url("https://www.google.com").build()
// 3. 응답
client.newCall(req).enqueue(object: Callback {
override fun onFailure(call: Call, e: IOException) {
}
override fun onResponse(call: Call, response: Response) {
CoroutineScope(Dispatchers.Main).launch {
val mTextMain = findViewById<TextView>(R.id.mTextMain)
mTextMain.text = response.body!!.string()
}
}
})
}
https://www.youtube.com/watch?v=yIdFRXHawYc