앱에서 네트워크 통신을 구현하려면 아래 퍼미션을 선언해야 한다.
<uses-permission android:name="android.permission.INTERNET" />
안드로이드 앱은 네트워크 통신을 할 때 기본으로 HTTPS 보안 프로토콜을 사용한다.
일반 HTTPS 프로토콜로 통신하려면 특정 도메인만 허용하도록 선언해 줘야 한다.
res/xml 폴더에 임의의 이름으로 XML파일을 만들고 다음처럼 작성한다.
<network-security-config>
<domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="true">HTTP 프로토콜로 접속 허용할 IP, 도메인 </domain>
</domain-config>
<network-security-config>
위의 파일을 매니페스트에 등록해서 해당 도메인에 한해서만 HTTP 통신이 가능하다.
<application
...
android:networkSecurityConfig="@xml/network_security_config">
또는 매니페스트에서 usesCleartextTraffic 속성을 true로 설정하면 앱 전체에서 모든 도메인의 서버와 HTTP 통신을 할 수 있다.
<application
android:usesCleartextTraffic="true">
HTTP 통신을 좀 더 쉽게 구현하게 해주는 라이브러리
Volley 라이브러리 등록
implementation 'com.android.volley:volley:1.2.1'
핵심 클래스는 RequestQueue와 XXXRequest 이다.
// 문자열 요청 정의
val stringRequest = StringRequest(
RequestMethod.POST,
url,
Response.Listener<String> {},
Response.ErrorListener {}
) {
override fun getParams(): MutableMap<String, String> {
return mutableMapOf<String, String>("one" to "hello", "two" to "world")
}
}
// 서버에 요청하기
val queue = Volley.newRequestQueue(this)
queue.add(stringRequest)
POST방식으로 서버에 요청할 때는 getParams() 함수를 재정의해서 작성하면 자동으로 호출된다.
val imageRequest = ImageRequest(
url,
Response.Listener { response -> binding.imageView.setImageBitmap(response) },
0,
0,
ImageView.ScaleType.CENTER_CROP,
null,
Response.ErrorListener {}
)
val queue = Volley.netRequestQueue(this)
queue.add(imageRequest)
서버에서 가져온 이미지를 화면에 출력만 한다면 NetworkImageView가 더 편리하다.
<com.android.volley.toolbox.NetworkImageView
android:id="@+id/networkImageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
위의 뷰를 작성하고 이 객체의 setImageUrl() 함수만 호출하면 서버에서 가져온 이미지를 출력하는 것까지 자동으로 이뤄진다.
RequestQueue의 add()함수를 호출하지 않아도 setImageUrl()을 통해 서버에 요청할 수 있다.
val queue = Volley.newRequestQueue(this)
val imgMap = HashMap<String, Bitmap>()
imageLoader = ImageLoader(queue, object : ImageLoader.ImageCache {
override fun getBitmap(url: String): Bitmap? {
return imgMap[url]
}
override fun putBitmap(url: String, bitmap: Bitmap) {
imgMap[url] = bitmap
}
})
binding.networkImageView.setImageUrl(url, imageLoader)
setImageUrl을 사용하면 서버 이미지를 가져오기 전에 getBitmap이 호출된다. 이 함수의 반환값이 널이면 서버로 이미지를 불러들어와 putBitmap() 함수가 호출된다. 서버 이미지를 putBitmap()두 번째 매개변수로 전달해준다.
// JSON 데이터 요청
val jsonRequest =
jsonObjectRequest(
Request.Method.GET,
url,
null,
Response.Listener<JSONObject> { response ->
val title = response.getString("title")
val date = response.getString("date")
},
Response.ErrorListener {}
)
val queue = Volley.newRequestQueue(this)
queue.add(jsonRequest)
// 서버로부터 아래의 JSON 데이터가 전달되었다는 가정 아래 작성한 코드이다.
{
"title": "제목",
"date": "2023-03-28"
}
// JSON 배열 요청
val jsonArrayRequest = JsonArrayRequest(
Request.Method.GET,
url,
null,
Response.Listener<JSONArray> { response ->
for (i in 0 until response.length()) {
val jsonObject = response[i] as JSONObject
val title = jsonObject.getString("title")
val date = jsonObject.getString("date")
}
},
Response.ErrorListener {}
)
val queue = Volley.newRequestQueue(this)
queue.add(jsonArrayRequest)
// 아래와 같은 JSON 데이터가 전달된다는 가정 아래 작성
[
{
"title": "제목",
"date": "2023-03-28"
},
{
"title": "제목",
"date": "2023-03-28"
}
]