GDSC HUFS 3기/Android with Kotlin Team 4

[4팀] 34. Android AsyncTask의 구조와 제작 사항

gusals42 2021. 12. 8. 04:00

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

작성자 : 정현민

개발환경은 Windows, Android Studio입니다. (본문3)

 

 

1. AsyncTask란?

비동기작업(Asynchronous)을 위해 사용하는 AsyncTask

비동기실행 기능은 "필요에 따라 만들어진 스레드가 메인스레드와 상호작용 후 종료"하는 형태로 동작

동기실행과 비교했을 때, 어떤 기능을 실행한 다음 그 기능의 실행이 완료될 때까지 대기할 것인지 아닌지의 여부에 따라 결정된다. 실행이 완료되지 않고 다른 기능이 실행되는 것이 비동기 실행기능.

 

출처-https://developer.android.com/reference/android/o

서울열린데이터광장의 오픈 API로 지도에 공공도서관의 위치를 출력하는 앱

 

2. 기본 설정

Google Map을 사용하기 위한 기본 설정을 해준다.

안드로이드 스튜디오 Welcome page에서 Configure 들어가서 SDK 설정을 해준다.

Google Play services를 체크박스에 체크하고 Apply해서 install 해준 후

New project를 Google Map Activity로 설정해주면 기본설정 끝!!

 

3. 서울시 열린데이터 광장에서 인증키와 API 가져오기

data.seoul.go.kr 접속 후 로그인

도서관 위치 정보 검색 후 서울특별시 공공도서관 현황정보 들어가기

Open API의 인증키 신청 클릭 

필수 작성요소 작성 후 인증키 신청 버튼 클릭하면 인증키 신청 완료!!

나의 화면-인증키 관리에서 발급받은 인증키 확인 가능

인증키복사 후 아까 들어갔던 서울특별시 공공도서관 현황정보 Open API의 샘플 URL 링크 복사

웹페이지에 붙여넣은 후 xml->json(인증키)->아까 복사한 인증키로 바꿔주면

이런 화면이 나타난다

 

✔샘플 URL의 마지막 숫자는 마지막 페이지를, 마지막에서 두번째 숫자는 시작페이지를 의미하므로 바꿔주면 원하는 페이지에 해당하는 정보를 얻을 수 있다!

4. JSON to KOTLIN class로 데이터 붙여넣기

위의 경로로 data package를 설정해준다.

이 전에 플러그인 setting이 필요해서 안드로이드 스튜디오의 File-Settings-Plugins를 들어가서

Json to Kotlin class를 install해준다.

Kotlin data class File from JSON을 선택해준 후 웹브라우저에서 복사한 데이터를 붙여넣기 한다.

format을 눌러주면 여러줄로 보이도록 해준다.

JSON format으로 된 data를 class 이름을 적어주면 kotlin file로 변환해준다.

✔여러 개의 class가 형성이 되고 그 class들을 library라는 큰 class로 묶여지는 것.

✔class명의 소문자가 대문자로 바뀌는 case가 존재-> 변수명 때문에 버그가 생길 수 있기 때문에 주의!!!

root에 SeoulOpenApi라는 class 생성

class SeoulOpenApi {
    companion object {
        val DOMAIN = "http://openapi.seoul.go.kr:8088/"
        val API_KEY = "74794d4d7a6a686d36356a654a5041"
    }
}

class에서 DOMAIN과 API_KEY를 선언해준다.

5. 네트워크 사용을 위한 retrofit 설정 + internet 설정

gradle file을 열고 Java 8버전을 사용하기 위한 설정을 해준다.

retrofit과 converter 설정(retrofit은 웹에 검색해서 오픈소스 사용)

converter란? 우리가 사용할 웹브라우저의 data를 kotlin class로 변환해주는 것 

✔converter과 retrofit의 버전 맞추는 것 중요!!

✔설정한 후 Sync Now!

 

//SeoulOpenApi.kt

//내가 사용할 서비스 정의
interface SeoulOpenService {
    @GET("{api_key}/json/SeoulPiblicLibraryInfo/1/{end}")
    fun getLibraries(@Path("api_key")key:String, @Path("end") limit:Int) : Call<library>
}

사용할 함수의 이름: getLibraries, parameter로 api_key를 문자열로 넘겨서 retrofit이 호출해주는 주소에 api_key 사용

limit을 통해 최댓값(숫자) 설정, call을 통해 return type 정의(최상위 class library 사용)

✔여러 개의 api_key를 사용하는 경우가 있기 때문에 지정해주지 않고 {api_key}로 설정!

//AndroidManifest
//인터넷을 통해 데이터를 가져올 것이기 때문에 꼭 필요한 작업!

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

5. 지도에서 도서관 위치가 나오도록 하는 코드 작성

fun loadLibraries(){
        val retrofit = Retrofit.Builder()
            .baseUrl(SeoulOpenApi.DOMAIN)
            .addConverterFactory(GsonConverterFactory.create())
            .build()

        val service = retrofit.create(SeoulOpenService::class.java)

        service.getLibraries(SeoulOpenApi.API_KEY, 200)

 

.enqueue(object : Callback<library>{
                override fun onResponse(call: Call<library>, response: Response<library>) {
                    val result = response.body()
                    showLibraries(result)
                }

                override fun onFailure(call: Call<library>, t: Throwable) {
                    //failure 시에 텍스트 표시 + error 사항 표시
                    Log.e("라이브러리", "error=${t.localizedMessage}")
                    Toast.makeText(this@MapsActivity, "데이터를 가져올 수 없습니다", Toast.LENGTH_LONG).show()

위에서 call한 library가 callback<library>로 return된다.

이 callback 인터페이스 안에 두 개의 함수가 설정되어 있다.

response할 경우와 failure할 경우에 맞춰서 코드 작성하면 된다.

fun showLibraries(result:library?) {
        //반복문을 돌려야하는 것은 row 변수
        //result가 null이 아니도록 let으로 설정
        result?.let{
            val latlngBounds = LatLngBounds.Builder()
            //library가 하나씩 꺼내지도록 반복문 설정
            for(library in it.SeoulPublicLibraryInfo.row){
                //position 설정 XCNTS:latitude에 해당, YDNTS:longtitude에 해당
                val position = LatLng(library.XCNTS.toDouble(), library.YDNTS.toDouble())
                //click했을 때 도서관 이름이 나오도록 title 설정
                val marker = MarkerOptions().position(position).title(library.LBRRY_NAME)
                //marker 넣어주기
                mMap.addMarker(marker)

                latlngBounds.include(position)
            }

            val bounds = latlngBounds.build()
            //마커가 잘리지 않도록 padding으로 여윳값 설정
            val padding = 0

            val camera = CameraUpdateFactory.newLatLngBounds(bounds, padding)
            mMap.moveCamera(camera)
        }
    }

GoogleMap에서 사용하기 쉬운 옵션 중 하나인 latlngBounds 사용 

latlngBounds를 사용하여 position값을 넣어주면, 마커들이 보일 수 있는 정도에 카메라를 위치시켜준다.

sydney로 설정되어 있던 map을 loadLibraries()로 바꿔준다.

 

        android:usesCleartextTraffic="true"

안드로이드 앱에서는 http가 되지 않기 때문에 manifest의 application 태그에 코드작성해주면

서울 데이터광장에서 다운받은 도서관 데이터를 기반으로 도서관 위치를 알려주는 앱이 만들어진다!

6. 앱 실행모습

앱이 실행된 모습

ʕง•ᴥ•ʔง