GDSC HUFS 3기/Android with Kotlin Team 5

[5팀] 코틀린 안드로이드 기초강의_50 | Android AsyncTask의 구조와 제작 사항

루이란 2021. 12. 10. 22:00

이 글은 이것이 안드로이드다 with 코틀린(개정판)를 참고하여 작성하였습니다.

작성자 : 임예람

개발환경은 Windows, Android Studio입니다.

📌참고: 이번 강의는 '53강:구글지도 Open API로 지도에 표시하기'와 내용이 겹친다

1. Android AsyncTask의 구조와 제작 사항

👉🏻 먼저 API 키를 발급받는다.

 

 

👉🏻주소를 복사해서 붙여넣기 하고 xml을 json으로 sample을 발급받은 인증키로 변경한다. 그러면 해당 조건에 맞는 내용이 나온다.

 

👉🏻데이터 패키지를 만들어주고 나서 코틀린 데이터 클래스에 json 정보를 붙여넣기 해준다. 이는 json을 코틀린 파일로 변환해주는 역할을 한다.

👉🏻클래스 이름을 Library로 해준다. 총 4개의 클래스가 생긴다.

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    kotlinOptions {
        jvmTarget = '1.8'
    }
    
    ...
    
    implementation 'com.squreup.retrofit2:retrofit:2.9.0'
    implementation 'com.squreup.retrofit2:converter-gson:2.9.0'

👉🏻람다 문법 사용해서 자바 버전을 지정해준다.

👉🏻retorfit과 converter 버전을 맞춰 설정해둔다.

class SeoulOpenApi {
    companion object {
        val DOMAIN = "http://openapi.seoul.go.kr:8088/" //api 주소
        val API_KEY = "--" //api 키
    }
}

//인터페이스(내가 사용할 서비스) 정의
interface SeoulOpenService {
    //받아오는 주소
    @GET("{api_key}/json/SeoulPublicLibraryInfo/1/{end}")
    //api키를 파라미터로 넘겨준다.
    //Call로 리턴타입 지정
    fun getLibraries(@Path("api_key") key:String, @Path("end") limit:Int) : Call<Library>
}

SeoulOpenApi.kt

👉🏻인터페이스 SeoulOpenService를 정의해준다.

👉🏻api키와 받아올 개수를 지정해 넘겨주면 해당 주소로 들어가 아까와 같이 정보를 받아올 수 있다.

👉🏻리턴타입은 Call로 지정해준다.

    fun loadLibaries() {
        //retrofit 사용을 위한 준비
        val retrofit = Retrofit.Builder()
            .baseUrl(SeoulOpenApi.DOMAIN)
             //json을 우리가 만든 클래스로 변환해주는 converter
            .addConverterFactory(GsonConverterFactory.create())
            .build()

        //앞에서 정의한 서비스를 가져온다.
        val service = retrofit.create(SeoulOpenService::class.java)
        //서비스에 있는 getLibraries 함수에 키와 몇 개 가져올 지 설정
        service.getLibraries(SeoulOpenApi.API_KEY, 200)
            //비동기로 실행해야 한다.
            //콜백의 Library로 리턴된다. 인터페이스가 콜백의 형태로 리턴되는 것.
            .enqueue(object: Callback<Library> {
                //인터넷을 통해 자료를 요청하면 그 자료를 반환해주는 것.
                //자료 반환 실패
                override fun onFailure(call: Call<Library>, t: Throwable ){
                    Toast.makeText(this@MapsActivity, "데이터를 가져올 수 없습니다", Toast.LENGTH_LONG).show()
                }
                //자료 반환 성공
                override fun onResponse(call: Call<Library>, response: Response<Library>){
                    //응답에 성공하면 대답이 body로 넘어오게 된다.
                    val result = response.body()
                    showLibraries(result)
                }
            })
    }

MapsActivity.kt

👉🏻converter를 이용해서 json을 우리가 만든 클래스로 변환한다.

👉🏻이전에 만든 인터페이스를 이용해 자료를 받아온다. 자료 반환을 성공했을 때와 실패했을 때를 대비해 함수를 2개 만들어준다.

    //들어오는 값이 null인지 '?'로 확인을 한다.
    fun showLibraries(result: Library?) {
        //result가 null이 되면 안 되니까 let으로 처리한다.
        result?.let{
            val latlngBounds = LatLngBounds.Builder()
            //Library를 하나씩 꺼내 반복문을 돌린다.
            //Library 정보 하나가 row로 변환되어서 들어온다.
            for(library in it.SeoulPublicLibraryInfo.row) {
                //XCNTS와 YDNTS를 double로 변환해서 위치 변수를 만들어 준다.
                val position = LatLng(library.XCNTS.toDouble(), library.YDNTS.toDouble())
                //Library 하나마다 마커를 생성해준다. 마커에 position과 이름을 넣어준다.
                val marker = MarkerOptions().position(position).title(library.LBRRY_NAME)
                //마커를 넣어준다.
                mMap.addMarker(marker)
                //position을 이용해 마커들를 화면 중앙에 위치시킨다.
                latlngBounds.include(position)
            }
            //전체 bounds를 계산하고 마커 잘리는 걸 방지하기 위해 패딩을 설정한다.
            val bounds = latlngBounds.build()
            val padding = 0
            //bounds를 연결해서 새로운 범주를 결정한다.
            val camera = CameraUpdateFactory.newLatLngBounds(bounds, padding)
            //해당 위치로 카메라를 이동시킨다.
            mMap.moveCamera(camera)
        }
    }

MapsActivity.kt

👉🏻받아온 정보를 반복문을 통해 돌려 데이터 한 개당 마커를 찍어준다.

✍🏻정보 하나를 row로 변환해준다.