본문 바로가기

모바일(Mobile)/안드로이드(Android)

[ANDROID] 안드로이드의 네트워크 통신 (HTTP 통신, Volley)

Volley란?

구글에서 개발한 안드로이드의 네트워크 프로그래밍용 라이브러리입니다.

안드로이드는 기본적으로 컴퓨터와 달리 네트워크 사용 시 권한 설정이 필요하고,

HTTP 통신을 할 경우에는 허용할 도메인 또는 IP 주소가 담긴 설정파일 (xml) 등을 통해 제한적으로 허용할 수 있습니다.

또는 AndroidManifest.xml 파일의 application 태그에 직접 설정을 추가하여 모든 도메인과 통신을 허용할 수 있습니다.

HTTP 요청의 메서드 GET, POST, PUT, DELETE 모두 사용 가능합니다. JavaScript의 fetch() 메서드와 비슷한 느낌입니다.

REST API로부터 데이터를 받아 뷰(View)에 표시하는 작업 등을 할 수 있습니다.

테스트용으로 사용하기 편한 REST API 서버는 아래의 링크 사이트를 추천합니다(사용이 직관적이고 샘플코드도 good).

https://jsonplaceholder.typicode.com/

 

JSONPlaceholder - Free Fake REST API

{JSON} Placeholder Free fake API for testing and prototyping. Powered by JSON Server + LowDB. Tested with XV. As of Oct 2022, serving ~1.7 billion requests each month.

jsonplaceholder.typicode.com

 

 

1. 모듈 수준의 gradle 파일에 의존성 추가 (build.gradle)

dependencies {

	(생략..)

    /* 구글에서 제공하는 네트워크 프로그래밍용 라이브러리 -> Volly */
    implementation 'com.android.volley:volley:1.2.1'

}

 

2. AndroidManifest.xml 파일에 인터넷 사용 권한 추가

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="co.test.sample">
    
    <uses-permission android:name="android.permission.INTERNET" /> <!-- 인터넷 권한 추가 -->

    <application
    	(후략..)

</manifest>

 

 

3.  Acitivity에서 사용하기 - GET

// 안드로이드에서 HTTP 통신을 위해서는 Volly의 프로퍼티인
// Volley.newRequestQueue 의 메서드 add를 사용해야 하는데,
// 그때 매개 변수로 사용될 StringRequest 객체
val stringRequest = StringRequest(
    Request.Method.GET, // HTTP 요청 메서드를 작성하고,
    "https://jsonplaceholder.typicode.com/todos/1", // 요청할 쿼리스트링 또는 URL을 작성한다
    Response.Listener<String>{  //
        Log.d("STR ::: ", "data is $it");
        textView1.text = it;
    },
    Response.ErrorListener{ error -> {
        Log.d("ERR ::: ", "error is $error");
    } }
)

val queue = Volley.newRequestQueue(this); // Volley의 다양한 요청 객체(XXXRequest)를 실행할 객체
queue.add(stringRequest);

 

4.  Acitivity에서 사용하기 - POST

 

// POST 요청용 객체
val stringRequest2 = object:StringRequest(
    Request.Method.POST,
    "https://jsonplaceholder.typicode.com/posts",
    Response.Listener<String> {
        Log.d("POST STR ::: ", "data is $it") // 요청 성공시 오는 데이터 작성
    },
    Response.ErrorListener { error -> {
        Log.d("POST ERR ::: ", "에러 발생... $error")
    }})
    // body에 담을 객체를 작성합니다.
    { override fun getParams(): MutableMap<String, String> {
            return mutableMapOf<String, String>("title" to "foo", "body" to "bar", "userId" to "1") ;
        }
    }

val queue = Volley.newRequestQueue(this); // Volley의 다양한 요청 객체(XXXRequest)를 실행할 객체
queue.add(stringRequest2);

 

이외에도 PUT이나 DELETE를 사용할 수 있긴 한데 테스트를 해보려면 직접 백엔드 서버를 만들어야 편하다.

당연히 HTTP 요청 메서드인 PUT이나 DELETE도 사용 가능한데 보통 서버를 직접 만들지 않는 이상,

데이터를 보내주는 서버는 GET 요청에 대한 API만 주로 개방되어 있고,

POST 나 PUT 정도는 경우에 따라 오픈되는 경우도 있는데 단순 데이터를 보내주는 서비스면

PUT도 잘 안열어 놓는 편이다(해커들에 의해 데이터 테러 가능성이 있음).

 

 

5.  Acitivity에서 사용하기 - ImageView에 이미지 세팅

val imgView = findViewById<ImageView>(R.id.imageView); // 이미지뷰를 객체로 바인딩한다.

// 이미지 뷰에 이미지를 불러오기 위한 요청 객체
val imageRequest = ImageRequest(
    "https://www.google.com/logos/doodles/2022/seasonal-holidays-2022-6753651837109831.4-law.gif", // 이미지를 받을 주소, bitmap 데이터를 수신
    Response.Listener { response -> img.setImageBitmap(response) }, // ImageView에 받아온 비트맵 데이터로 바로 세팅 가능!
    0, // 화면 크기 설정들 처음은 maxWidth
    0, // 그 다음은 maxHeight 두 값을 0으로 하면 wrap-content의 효과, 즉 준대로 크기 맞춘다.
    ImageView.ScaleType.CENTER_CROP,
    null, // 복호화 설정
    Response.ErrorListener {  error -> Log.d("IMG ERR ::: ", "$error") } // 서버에서 에러를 받았을 때 대응할 리스너
)

val queue = Volley.newRequestQueue(this); // Volley의 다양한 요청 객체(XXXRequest)를 실행할 객체
queue.add(imageRequest);

 

5.  Acitivity에서 사용하기 - NetworkImageView 에 이미지 세팅

Volley를 설치하면 Volley와 함께 쓰기 편한 전용 이미지 뷰(NetworkImageView)도 제공된다.

이 뷰를 통해서도 이미지를 세팅하여 ImageView로 사용 가능하다.

 

엑티비티 레이아웃에 추가한 NetworkImageView 

    <com.android.volley.toolbox.NetworkImageView
        android:id="@+id/network_image_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

 

액티비티에서의 사용

// Volly에서는 ImageView 를 아예 제공해준다. -> NetworkImageView
// HTTP 통신을 통해 가져온 데이터를 바로 이미지 뷰로 만들어 표현

val ntImgView = findViewById<NetworkImageView>(R.id.network_image_view);
val imgMap = HashMap<String, Bitmap>();
val 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!!;
    }
});

ntImgView.setImageUrl("https://www.mofa.go.kr/common-embd/images/eg-ko/main_visual_notext.jpg", imageLoader);

 

6.  Acitivity에서 사용하기 - JSON Object

// JSON 데이터 받기
val jsonRequest = JsonObjectRequest(
    Request.Method.GET,
    "https://jsonplaceholder.typicode.com/todos/1",
    null,
    Response.Listener<JSONObject> { response -> 
        // 응답의 결과가 JSON이므로 데이터 추출 가능
        val tag = "JSON DATA :::: "
        val userId = response.getString("userId")
        val id = response.getString("id");
        val title = response.getString("title");
        val completed = response.getString("completed");
        Log.d(tag, "data is : $userId, $id, $title, $completed")
    },
    Response.ErrorListener { error ->  Log.d("JSON ERR :::: ", "$error") }
)

val queue = Volley.newRequestQueue(this); // Volley의 다양한 요청 객체(XXXRequest)를 실행할 객체        
queue.add(jsonRequest);

 

6.  Acitivity에서 사용하기 - JSON Object Arraty

// https://jsonplaceholder.typicode.com/posts
// JSON 배열 요청
val jsonArrayRequest = JsonArrayRequest(
    Request.Method.GET,
    "https://jsonplaceholder.typicode.com/posts",
    null,
    Response.Listener<JSONArray> { response ->
        val tag = "JSON ARR DATA :::: "        
        for( i in 0 until response.length()){
            val jsonObject = response[i] as JSONObject;
            val userId = jsonObject.getString("userId")
            val id = jsonObject.getString("id");
            val title = jsonObject.getString("title");
            val body = jsonObject.getString("body");
            Log.d(tag, "data is : $userId, $id, $title, $body")
        }
    },
    Response.ErrorListener { error -> Log.d("JSON ARR ERR", "$error")  }
)

val queue = Volley.newRequestQueue(this); // Volley의 다양한 요청 객체(XXXRequest)를 실행할 객체        
queue.add(jsonArrayRequest);