Web | App/Android

[Kotlin] Retrofit2 + OkHttp로 API request 시작기

며용 2020. 12. 6. 02:59

- Retrofit

square.github.io/retrofit/

 

Retrofit

A type-safe HTTP client for Android and Java

square.github.io

 

안드로이드에서 사용가능한 REST Client (서버 통신을 위한 라이브러리)

Retrofit은 HTTP요청에 OkHttp 라이브러리를 사용함

 

처음에 Asynctask를 알려주셨었는데 Asynctask는 어렵고 시간도 많이 들고 해서 안드로이드에서 deprecated 되었다고 한다

 

 

 

 

 

 

1. build.gradle(Module:) > dependencies에 Retrofit, OkHttp 추가

// Retrofit: 서버와 통신
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'

//OkHttp: 통신 로그 확인하기 위함
implementation 'com.squareup.okhttp3:okhttp:3.14.9'
implementation 'com.squareup.okhttp3:logging-interceptor:3.11.0'

 

2. manifest에 통신을 위한 permission 추가

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

 

 

 

 

 

3. json 파싱을 위한 data class

abstract class ResponseData {
    val message: String? = null
    val code: String? = null
    val error_message: String? = null
}
data class ContentResult (
    @SerializedName("Content")
    val content: List<ContentModel> = emptyList()
) : ResponseData()

data class ContentModel(
	//변수명과 json key 값을 다르게 사용하고 싶은 경우 @SerializedName annotation 사용
    @SerializedName("author")
    val author: String = "",
    @SerializedName("category")
    val category: String = "",
)

 

 

 

 

 

4. API interface 작성

interface retrofitAPI {

    @GET("api/sample/get")
    fun getContent(
        @Header("authorization") authorization: String,
        //Query = URL?user_name=userName&.. 이런 식
        @Query ("user_name") userName: String,
    ): Call<ContentResult>

    @FormUrlEncoded //"Content-Type: application/x-www-form-urlencoded"
    @POST("api/sample/post")
    fun logIn(
        @Header("authorization") authorization: String,
        @Field("") field: String,
    ): Call<LoginResult>
    
    @GET
    fun getThumbnail(
    	//base url 대신 이 url로 요청함
        @Url url: String
    ): Call<ResponseBody>

    @GET("api/sample/{uuid}")
    fun getContentWithUUID(
    	//base url + api/sample/uuid로 
        //uuid는 넘겨주는 값으로 들어감
        @Path("uuid") uuid: String,
    ): Call<ResponseBody>
}

 

 

 

 

 

5. Retrofit.Builder 로 Retrofit 객체를 초기화

private val BASE_URL = "https://test.url"
private val API_KEY = "sample"
    
class sampleService {

    private val TAG = this::class.java.simpleName

    private var retrofitService : retrofitAPI ?= null
    private val client: OkHttpClient

    //초기화
    init {
        //로그 설정
        val interceptor = HttpLoggingInterceptor().apply {
            level = HttpLoggingInterceptor.Level.BODY
        }

        client = OkHttpClient.Builder()
            .addInterceptor(interceptor)
            .build()

        createRetrofitApi()
    }
    
    private fun createRetrofitApi() {
        retrofitService = Retrofit.Builder()
            .baseUrl(BASE_URL)
            .client(client)
            .addConverterFactory(GsonConverterFactory.create())
            .build()
            .create(retrofitAPI::class.java) //자바코드의 class 함수 사용 방법
    }

 

 

 

 

 

6. 서버 통신 콜백 함수

    fun getContentList(
        success: (List<ContentModel>) -> Unit,
        error: (Call<ContentResult>, Throwable) -> Unit
    ) {

        val call = retrofitService!!.getContent($API_KEY)

		//enqueue: Queue 에 삽입한다
        call.enqueue(object : Callback<ContentResult> {

            override fun onResponse(
                call: Call<ContentResult>,
                response: Response<ContentResult>
            ) {
                if (response.isSuccessful) {
                    val data = response.body()?.Content //?로 null체크

//                    Log.d(TAG, "Parsed: $data")
                    data?.let { success(data) } //null이 아닌 경우 실행
                } else {
                    Log.d(TAG, "${response.body()?.toString()}")
                }
            }

            override fun onFailure(call: Call<ContentResult>, t: Throwable?) {
                Log.d(TAG, "실패 : {$t}")
                call.let {
                    if (t != null) {
                        error(it, t)
                    }
                }
            }
        })
    }

 

 

 

 

 

 

Reference:

medium.com/mj-studio/%EC%84%9C%EB%B2%84-%EC%9D%91%EB%8B%B5-cherry-pick-okhttp-interceptor-eaafa476dc4d

https://gun0912.tistory.com/50

square.github.io/retrofit/2.x/retrofit/retrofit2/Retrofit.html#create-java.lang.Class-

square.github.io/okhttp/3.x/okhttp/okhttp3/OkHttpClient.Builder.html#readTimeout-long-java.util.concurrent.TimeUnit-

zerogdev.blogspot.com/2018/09/kotlin-shortcuturl1.html

 

 

 

 

 


https://github.com/Jeunna/TIL/tree/master/Android/firstApp/app/src/main/java/com/example/firstapp/network

 

GitHub - Jeunna/TIL: Today I Learned

Today I Learned. Contribute to Jeunna/TIL development by creating an account on GitHub.

github.com

나중에 구글 샘플 예제들을 보고 콜백 함수를 버렸다

 

서버 정보들 뺀다고 스켈레톤 코드가 되어버렸지만 아무튼,,

 

 

 

rest api는 코루틴 suspend를 사용하는 방식으로 변경했다

 

 

 

그리고 뭐 이미지 로딩할 때 successful이면 detail을 가져오고 failed면 error 이미지를 뜨게 짠 거 같다.

 

 

 

https://jeunna.tistory.com/141?category=823911 

 

[Kotlin] RecyclerView, 리스트 리소스 관리

이런 유튜브처럼, 스크롤을 내려보면 리스트가 계속 나오는 어플을 먼저 구현하라고 하셨다 리소스 관리하면서 하라고 하셔서 리소스 재사용을 할 수 있는 RecyclerView로 구현하게 되었다 RecycelrVi

jeunna.tistory.com

서버 코드는 구글 샘플 코드 참고해서 수정했었다.

샘플 코드 최고,,