일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- View
- sqlite
- 알고리즘
- onLayout
- LiveData
- CoordinatorLayout
- DataBinding
- AppBarLayout
- 백준
- recyclerview
- hilt
- 알림
- activity
- Behavior
- 안드로이드
- kotlin
- BOJ
- room
- Android
- onMeasure
- HTTP
- Algorithm
- 코틀린
- CollapsingToolbarLayout
- Coroutine
- CustomView
- notification
- Navigation
- ViewModel
- lifecycle
- Today
- Total
개발일지
Android in A..Z - HTTP (Volley) 본문
Volley
Volley는 2013년 구글에서 발표한 Android HTTP 라이브러리 입니다. (JavaScript에 Ajax와 매우 비슷한 구조이다.)
기존의 URLConnnection은 Request를 위한 기본 설정과 Thread를 만들어서 처리하는 보일러 코드가 필요하다는 단점이 있습니다.
Volley는 Callback으로 Response와 Error를 쉽게 처리할 수 있고, 비동기/동기 등 다양한 기능을 지원합니다.
Volley는 간단한 HTTP 통신에는 적합하지만. 모든 응답을 메모리에 유지하기 때문에 대용량의 전송은 적합하지 않습니다.
Dependency
dependencies {
// Volley
implementation 'com.android.volley:volley:1.2.0'
}
Volley 장점
- 네트워크 요청의 자동 예약
- 여러 개의 동시 네트워크 연결
- 표준 HTTP 캐쉬 일관성을 갖춘 투명한 디스크 및 메모리 응답 캐싱
- 요청 우선순위 지정 지원
- 요청 취소 지원
- 용이한 맞춤설정 (재시도, 백오프)
Volley Singleton
class VolleyHTTP private constructor(context: Context) {
companion object {
private var instance: VolleyHTTP? = null
fun getInstance(context: Context): VolleyHTTP {
return instance ?: synchronized(this) {
instance ?: VolleyHTTP(context).also {
instance = it
}
}
}
}
private val queue by lazy { Volley.newRequestQueue(context) }
fun<T> request(req: Request<T>) {
queue.add(req)
}
}
StringRequest
String형식의 Response를 받을 때 사용합니다. 생성자는 Method, URL, Response.Listener, Response.ErrorListener를 필요로 합니다.
val request = object : StringRequest(method, url,
{
binding.resultTextView.text = it
},
{
binding.resultTextView.text = it.toString()
}
) {
override fun getHeaders(): MutableMap<String, String> {
Log.d("PASS", "Call getHeaders($selectedContentType, $selectedMethod)")
return HashMap<String, String>(super.getHeaders()).apply {
put("Content-Type", "application/x-www-form-urlencoded")
}
}
override fun getParams(): MutableMap<String, String>? {
Log.d("PASS", "Call getParams($selectedContentType, $selectedMethod)")
return if (method == Method.POST) {
val parameter1 = binding.parameter1InputLayout.editText!!.text.toString()
val parameter2 = binding.parameter2InputLayout.editText!!.text.toString()
HashMap<String, String>().apply {
put("parameter1", parameter1)
put("parameter2", parameter2)
}
} else {
super.getParams()
}
}
}
VolleyHTTP.getInstance(requireContext()).request(request)
추가적으로 Header나 Parameter, Body등 설정 사항이 있으면 object로 일회용 객체를 받아서 필요한 함수를 Override하면 됩니다.
Method가 GET일 때는 getBody(), getParamter() 등 HTTP표준에 어긋나는 함수들은 호출되지 않습니다.
JsonRequest
Json형식의 Response를 받을 때 사용합니다. 생성자로 Method, URL, JSONObject(Parameter), Respose.Listener, Response.ErrorListener를 필요로 합니다.
val parameter1 = binding.parameter1InputLayout.editText!!.text.toString()
val parameter2 = binding.parameter2InputLayout.editText!!.text.toString()
val parameters = JSONObject(hashMapOf<Any?, Any?>("parameter1" to parameter1, "parameter2" to parameter2))
val request = JsonObjectRequest(method, getURL(), parameters,
{
binding.resultTextView.text = it.toString()
},
{
binding.resultTextView.text = it.toString()
}
)
VolleyHTTP.getInstance(requireContext()).request(request)
추가적으로 Header나 Parameter, Body등 설정 사항이 있으면 object로 일회용 객체를 받아서 필요한 함수를 Override하면 됩니다.
Method가 GET일 때는 getBody(), getParamter() 등 HTTP표준에 어긋나는 함수들은 호출되지 않습니다.
Method가 POST일 때는 Content-Type이 application/json으로 설정됩니다.
RequestFuture
Volley는 기본적으로 비동기를 지원하지만 RequestFuture를 통해 동기로 처리할 수 있습니다.
RequestFuture의 Template를 Response받을 형식으로 설정하고, Request객체에 Response.Listener와 Response.ErrorListener를 RequestFuture로 대체합니다.
val parameter1 = binding.parameter1InputLayout.editText!!.text.toString()
val parameter2 = binding.parameter2InputLayout.editText!!.text.toString()
val parameters = JSONObject(hashMapOf<Any?, Any?>("parameter1" to parameter1, "parameter2" to parameter2))
val requestFuture = RequestFuture.newFuture<JSONObject>()
val request = object : JsonObjectRequest(Method.POST, "${Server.PROTOCOL}://${Server.IP}:${Server.PORT}/application/json", parameters, requestFuture, requestFuture) {
override fun getHeaders(): MutableMap<String, String> {
return HashMap<String, String>(super.getHeaders()).apply {
put("Content-Type", "application/json")
}
}
}.apply {
// timeOutMs += timeOutMs * backoffMultiplier
retryPolicy = DefaultRetryPolicy(1000, 2, 3.0F)
}
VolleyHTTP.getInstance(requireContext()).request(request)
thread {
val jsonObject = requestFuture.get()
CoroutineScope(Dispatchers.Main).launch {
binding.resultTextView.text = jsonObject.toString()
}
}
Policy
TimeOut, Retry, BackOff를 설정할 때 사용합니다. 생성자로 TimeOut, RetryCount, Backoff를 통해 DefaultRetryPolicy를 만들어서 설정한다.
val request = object : JsonObjectRequest(Method.POST, "${Server.PROTOCOL}://${Server.IP}:${Server.PORT}/application/json", parameters, requestFuture, requestFuture) {
override fun getHeaders(): MutableMap<String, String> {
return HashMap<String, String>(super.getHeaders()).apply {
put("Content-Type", "application/json")
}
}
}.apply {
// timeOutMs += timeOutMs * backoffMultiplier
retryPolicy = DefaultRetryPolicy(1000, 2, 3.0F)
}
Git (예제코드)
github.com/KangTaeJong98/Example/tree/main/Android/HTTP
'Android (안드로이드) > HTTP' 카테고리의 다른 글
Android in A..Z - HTTP (Retrofit2) (0) | 2021.03.16 |
---|---|
Android in A..Z - HTTP (URLConnection) (0) | 2021.03.12 |
Android in A..Z - HTTP (개념) (0) | 2021.03.12 |