본문 바로가기
Android

[Kotlin] HttpUrlConnection 사용하여 api 호출하기

by bryan.oh 2023. 8. 2.
반응형

 

결과 화면

manifest 에 권한 추가

위치는 여기

<uses-permission android:name="android.permission.INTERNET" />

 

 

Activity 생성

HttpActivity

 

ViewBinding 하도록 소스 수정

class HttpActivity : AppCompatActivity() {
    private lateinit var binding: ActivityHttpBinding
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityHttpBinding.inflate(layoutInflater)
        setContentView(binding.root)
        
        
    }
}

 

layout 

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".HttpActivity">
    
    <EditText
        android:id="@+id/http_url_edit_text"
        android:layout_width="match_parent"
        android:layout_height="100dp" />
    
    <Button
        android:id="@+id/http_send_button"
        android:layout_width="match_parent"
        android:layout_height="52dp"
        android:text="SEND" />
    
    <TextView
        android:id="@+id/http_result_text_view"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1" />

</LinearLayout>

 

UI Thread 가 아닌 Background Thread 에서 작업하기 위해서 ThreadExecutor 를 생성

백그라운드 스레드를 사용하는 이유는 메인(UI) 스레드에서 긴 작업을 수행하면 앱이 응답하지 않거나 끊어지는 문제를 피하기 위해서입니다
class HttpActivity : AppCompatActivity() {
    val executor: ExecutorService = Executors.newSingleThreadExecutor()
    
}

버튼 클릭하면 실행 하도록, onCreate 안에 click event 작성

binding.httpSendButton.setOnClickListener {
    executor.execute{
        val url = binding.httpUrlEditText.text.toString()
        request(url)
    }
}
Executor 를 사용하지 않고 Thread 를 사용할 수 도 있습니다.
    binding.httpSendButton.setOnClickListener {
        Thread {
            val url = binding.httpUrlEditText.text.toString()
            request(url)
        }.start()
    }

 

fun request 를 만들고 그 안에 내용 추가

fun request(url: String){
    var url = URL(url)
    (url.openConnection() as? HttpURLConnection)?.run {
        connectTimeout = 10000
        requestMethod = "GET"
        setRequestProperty("Content-Type", "application/json; charset=utf-8")
        setRequestProperty("Accept", "application/json")
        doInput = true

        if (responseCode == HttpURLConnection.HTTP_OK) {
            val streamReader = InputStreamReader(inputStream)
            val buffered = BufferedReader(streamReader)

            val content = StringBuilder()
            while (true) {
                val data = buffered.readLine() ?: break
                content.append(data)
            }

            buffered.close()
            disconnect()

            Log.d("RETURN", "$content")

            runOnUiThread {
                binding.httpResultTextView.setText(content)
            }
        }

    }

    Log.d("HTTP_RESULT", "END-------")
}

 

 

실행

시뮬레이터를 실행하고 다음 url을 입력하고 실행하면 다음과 같은 결과가 나옵니다.

https://date.nager.at/api/v2/publicholidays/2023/KR 

 

 

참고

Background Thread 에서 실행하므로, 아래와 같은 코드가 있을 때, (request() 함수 안에서는 println("request") 를 합니다)

print 찍히는 순서는, 다음과 같습니다.

binding.httpSendButton.setOnClickListener {
    for (i in 1..10){
        println("for $i")
        if (i == 3) {
            executor.execute {
                println("execute $i")
                val url = binding.httpUrlEditText.text.toString()
                request(url)
            }
        }
        Thread.sleep(50)
    }
}

728x90
반응형

댓글