안드로이드 세계

[Android] Retrofit2 사용법 본문

안드로이드(Android)/코틀린(Kotlin)

[Android] Retrofit2 사용법

리안94 2021. 5. 1. 04:33

오늘은 안드로이드 네트워크 통신에 일반적으로 사용하는 Retrofit에 대해서 알아볼 것이다.

 

Retrofit이란?

- Retrofit is a networking library used to implement a type-safe REST client for Android.

 

직역을 하면, Android용으로 Type-Safe REST 클라이언트를 구현하는 데 사용되는 라이브러리이다.

 

사용법은 처음 사용하게 된다면 조금 복잡할 수 있는데, 몇 번 사용하다 보면 이해가 될 것이다.

 

Setp 1. 라이브러리 Gradle에 추가

 

아래의 코드를 모듈 그래들단의 dependencies에 추가해준다.

def retrofit_version = '2.9.0'
implementation "com.squareup.retrofit2:retrofit:$retrofit_version"
implementation "com.squareup.retrofit2:converter-gson:$retrofit_version"

//네트워크 통신 로그를 보기위한 interceptor를 추가
implementation 'com.squareup.okhttp3:okhttp:4.2.1'
implementation 'com.squareup.okhttp3:logging-interceptor:4.2.1'

추가한 다음 우측 상단의 Sync Now를 클릭한후 싱크가 완료될 때까지 기다려준다.

 

Setp 2. 파싱해올 api선정

- 공공데이터 포털에서 제공하는 한국 환경공단_에어코리아_대기오염정보의 시도별 실시간 측정 정보 조회를 사용

 

먼저 공공데이터 포털에 접속한다.

 

www.data.go.kr/

 

공공데이터 포털

국가에서 보유하고 있는 다양한 데이터를『공공데이터의 제공 및 이용 활성화에 관한 법률(제11956호)』에 따라 개방하여 국민들이 보다 쉽고 용이하게 공유•활용할 수 있도록 공공데이터(Datase

www.data.go.kr

 

회원가입을 한 후, 미세먼지를 검색하고 오픈 API를 살펴보면 2페이지에 한국환경공단_에어코리아_대기오염정보가 있다.

 

 

우측 상단의 활용신청을 누른후 활용 목적에 앱 개발을 선택한 후 내용을 적고, 개발용으로 작성한 뒤 신청하면 된다.

 

신청이 완료되면 위와 같은 화면으로 이동하게 되는데 End Point는 추후에 사용할 BaseUrl이 될 것이다.

 

ServiceKey는 여기서 제공받은 인증키를 뜻한다.

 

Step 3. PostMan으로 확인하기

코드를 작성하기 전에 API에 응답이 어떻게 오는지를 확인해보아야 한다.

 

먼저 PostMan을 다운로드한다.

 

www.postman.com/downloads/

 

Download Postman | Try Postman for Free

Try Postman for free! Join 13 million developers who rely on Postman, the collaboration platform for API development. Create better APIs—faster.

www.postman.com

 

실행을 하면 아래와 같은 화면이 나오게 되는데, +버튼을 누른다.

 

GET방식으로 실행할 것이고, 더 자세한 주소는 오픈 API의 참고문헌을 보면 된다.

 

주소를 다 적은 뒤 SEND를 눌렀을 때, 아래와 같이 나오면 성공한 것이다.

 

servicekey는 Encoding을 사용하면 되고, returnType은 JSON을 이용할 것이기 때문에 JSON을 입력하면 된다.

 

해당사진은 실수로 returnType을 xml로 했지만 json으로 하여야한다.

 

※ 활용 신청을 한 뒤, 인증키는 즉시~하루 정도의 시간이 걸릴 수 있기 때문에, SERVICEKEY IS NOT REGIST ERROR가 발생하는 경우는 기다리면 된다.

 

Setp 4. Json을 이용하여 POJO클래스 만들기

 

PostMan의 결과로 나온 부분을 전체 복사하여 아래의 사이트에 다음과 같이 넣어준다.

 

www.jsonschema2pojo.org/

 

jsonschema2pojo

Reference properties For each property present in the 'properties' definition, we add a property to a given Java class according to the JavaBeans spec. A private field is added to the parent class, along with accompanying accessor methods (getter and sette

www.jsonschema2pojo.org

 

 

PreView를 눌러주게 되면 POJO클래스로 변환해준다.

 

자바를 사용하게 되면 클래스를 복사한 후 붙여 넣기를 하면 되지만 우리는 코틀린을 이용할 것이기 때문에 조금의 변환은 필요하다. (복사 붙여 넣기를 해도 IDE에서 자동으로 변환해주기는 한다.(정확하게 변환은 되지 않음.))

 

DustPOJO.kt를 생성해준다.

data class Dust(val response: DustResponse)

data class DustResponse(
    @SerializedName("body")
    val dustBody: DustBody,
    @SerializedName("header")
    val dustHeader: DustHeader
)

data class DustBody(
    val totalCount: Int,
    @SerializedName("items")
    val dustItem: MutableList<DustItem>?,
    val pageNo: Int,
    val numOfRows: Int
)

data class DustHeader(
    val resultCode: String,
    val resultMsg: String
)

data class DustItem(
    val so2Grade: String,
    val coFlag: String?,
    val khaiValue: String,
    val so2Value: String,
    val coValue: String,
    val pm25Flag: String?,
    val pm10Flag: String?,
    val o3Grade: String,
    val pm10Value: String,
    val khaiGrade: String,
    val pm25Value: String,
    val sidoName: String,
    val no2Flag: String?,
    val no2Grade: String,
    val o3Flag: String?,
    val pm25Grade: String,
    val so2Flag: String?,
    val dataTime: String,
    val coGrade: String,
    val no2Value: String,
    val stationName: String,
    val pm10Grade: String,
    val o3Value: String
)

POJO클래스 생성이 완료되었다.

 

Step5. Retrofit을 생성

 

먼저 NetWorkInterface를 만들어준다.

interface NetWorkInterface {

    @GET("getCtprvnRltmMesureDnsty") //시도별 실시간 측정정보 조회 주소
    suspend fun getDust(@QueryMap param: HashMap<String, String>): Dust

}

 

자바에서 레트로핏을 이용할 때에는 아래와 같다.

@GET("getCtprvnRltmMesureDnsty")
public Call<Dust> getDust(@QueryMap param: HashMap<String, String>)

Call키워드를 붙여주었지만, 코틀린에서 코루틴을 사용하는경우 붙여도 되고 안 붙여도 된다.

 

그리고 레트로핏을 생성해줄 NetWorkClient도 생성해준다.

 

object NetWorkClient {

    private const val DUST_BASE_URL = "http://apis.data.go.kr/B552584/ArpltnInforInqireSvc/"


    private fun createOkHttpClient(): OkHttpClient {
        val interceptor = HttpLoggingInterceptor()

        if (BuildConfig.DEBUG)
            interceptor.level = HttpLoggingInterceptor.Level.BODY
        else
            interceptor.level = HttpLoggingInterceptor.Level.NONE

        return OkHttpClient.Builder()
            .connectTimeout(20, TimeUnit.SECONDS)
            .readTimeout(20, TimeUnit.SECONDS)
            .writeTimeout(20, TimeUnit.SECONDS)
            .addNetworkInterceptor(interceptor)
            .build()
        }

    private val dustRetrofit = Retrofit.Builder()
        .baseUrl(DUST_BASE_URL).addConverterFactory(GsonConverterFactory.create()).client(createOkHttpClient()).build()

    val dustNetWork: NetWorkInterface = dustRetrofit.create(NetWorkInterface::class.java)

}

여기에서 BuildConfig가 빨간색으로 변하고 임포트도 할 게 없다면 Build -> Rebuild를 한번 해주면 해결이 된다.

 

Step 6. Retrofit통신

 

MVVM을 이용할 것이기 때문에 ViewModel안에서 네트워크 통신을 하게 된다.

 

먼저 viewModel에서 Coroutine을 사용하기 위해 디펜던시를 추가해준다.

 

그리고 activity-ktx도 추가해준다.

def arch_lifecycle_version = '2.3.1'
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$arch_lifecycle_version"

def activity_version = "1.2.2"
implementation "androidx.activity:activity-ktx:$activity_version"

 

DustViewModel을 만들어준다.

class DustViewModel: ViewModel(){

    private val _dustData = MutableLiveData<Dust>()
    val dustData: LiveData<Dust>
        get() = _dustData

    fun communicateNetWork(param: HashMap<String, String>) = viewModelScope.launch(Dispatchers.IO){

        val responseData = dustNetWork.getDust(param)

        withContext(Dispatchers.Main) {
            _dustData.value = responseData
        }

    }

}

 

그리고 화면으로 보여줄 것이 아닌 로그로 보여줄 것이기 때문에 액티비티는 다음과 같이 작성한다.

class MainActivity : AppCompatActivity() {

    private val dustViewModel by viewModels<DustViewModel>()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        dustViewModel.communicateNetWork(setUpDustParameter())
        observeDustData()
    }
    
    private fun observeDustData(){
        dustViewModel.dustData.observe(this){
            it?.let {
                Log.e("Parsing Dust ::", it.toString())   
            }
        }
    }

    private fun setUpDustParameter(): HashMap<String, String>{

        return hashMapOf(
            "serviceKey" to "DUST_DECODING_SERVICE_KEY", // OPEN API 의 인증키 중 Decoding된 것을 사용 
            "returnType" to "json",
            "numOfRows" to "100",
            "pageNo" to "1",
            "sidoName" to "서울",
            "ver" to "1.0"
        )

    }
}

 

마지막으로 매니페스트에서 인터넷 퍼미션과 usesCleartextTraffic를 설정해준다.

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

<application
    android:usesCleartextTraffic="true"
    ...
    >
</application>

 

 

실행결과는 다음과 같다.

 

 

샘플로 사용한 코드

github.com/pyg1007/Retrofit2-Sample

 

pyg1007/Retrofit2-Sample

Contribute to pyg1007/Retrofit2-Sample development by creating an account on GitHub.

github.com

 

Comments