본문 바로가기
App/Android

[2021.11.01] How to use Retrofit2 with android Using Kotlin?

by injekim97 2021. 11. 1.
반응형

[2021.11.01] How to use Retrofit2 with android Using Kotlin?

 

 

 

 

우선 Retrofit2 개념을 간단하게 알아본 후, 안드로이드에서 고틀린과 함께 Retrofit2를 사용하는 방법에 대해 알아보자 

 

 

 

 

https://square.github.io/retrofit/

 

Retrofit

A type-safe HTTP client for Android and Java

square.github.io

-> Retrofit document 

 

 

 

 

* Retrofit 이란?

-> REST API 통신을 위해 구현된 라이브러리

 

 

 

* Retrofit을 사용하는 이유?

-> 다른 라이브러리에 비해 간단한 구현 방법과 성능이 좋기 때문

-> 동기/비동기 방식을 선택, Call의 요청을 취소 가능

 

 

 

 

 

* Retrofit2 3가지 구성요소

DTO (POJO) 

-> 'Data Transfer Object', 'Plain Old Java Object' 형태의 모델(Model) / JSON 타입변환에 사용

 

Interface

-> 사용할 HTTP CRUD동작(메소드) 들을 정의해놓은 인터페이스

* CRUD ( Create / Read / Update / Delete ) -> HTTP Method ( POST / GET / PUT / DELETE )

 

Retrofit.Builder 클래스

-> Interface를 사용할 인스턴스, baseUrl(URL) / Converter(변환기) 설정

 

 

 


* HTTP Method
POST : 리소스 생성
GET : 리소스 조회 및 출력
PUT : 리소스 수정
PATCH : 리소스 수정
DELETE : 리소스 삭제

 

* PUT과 PATCH 차이점
-> PUT은 해당 리소스의 전체를 교체, PATCH는 일부를 변경 

 

 

 

 


HTTP 응답 코드
1xx : 요청을 받았으며 프로세스를 계속함 (정보)
2xx : 클라이언트의 요청을 정상적으로 수행 (성공)
3xx : 요청 완료를 위해 추가적인 작업 조치가 필요함 (리다이렉션)
4xx : 요청의 문법이 잘못되었거나 요청을 처리할 수 없음 (클라이언트 오류)
5xx : 서버가 명백히 유효한 요청에 대해 실패함 (서버 오류)


https://ko.wikipedia.org/wiki/HTTP_%EC%83%81%ED%83%9C_%EC%BD%94%EB%93%9C

 

HTTP 상태 코드 - 위키백과, 우리 모두의 백과사전

아래는 HTTP(하이퍼텍스트 전송 프로토콜) 응답 상태 코드의 목록이다. IANA가 현재 공식 HTTP 상태 코드 레지스트리를 관리하고 있다. 모든 HTTP 응답 코드는 5개의 클래스(분류)로 구분된다. 상태 코

ko.wikipedia.org

-------------------------------------------------------------------------------------------------------------------------

Retrofit2 사용 방법

 

 

목차

1. 테스트 할 API (Github API)
2. DTO CLASS 생성
3. API Interface 생성
4. RetrofitBuilder 생성
5. API 확인을 위한 XML 작성
6. Activity에 API 호출

 

 

 

 

1. 테스트 할 API (Github API)

https://api.github.com/users/아이디

e.g : https://api.github.com/users/injekim97

* email,bio,followers 등 왼쪽에 있는 것들이 전부 key 값

 

--------------------------------------------------------------------------------------------------------------------------

2. DTO CLASS 생성

위의 사진을 보면 많은 정보가 있지만, 아이디와 팔로우, 팔로잉 수만 안드로이드 앱으로 가져오도록 해보자 .

* JSON 데이터를 받아올 UserInfo라는 DTO 클래스를 생성하자.,

* 변수의 이름을 JSON "키:값"과 이름을 맞춰 매핑하거나 @SerializedName을 통해 매핑 가능

 

 


New -> Kotlin Class/file

 

 

 

→ data class 클릭

 

 

* data class에 선언해 줄 코드(UserInfo.kt)

import com.google.gson.annotations.SerializedName //import 추가로 Unresolved reference: SerializedName 에러 해결


data class UserInfo(
    @SerializedName("login")
    val userId: String,
    val blog: String,
    val bio: String,
    val public_repos: Int,
)

-> 유저 아이디, 팔로워 수, 팔로잉 수

 

 

 

* @SerializedName 에러를 해결 하려면?

implementation 'com.google.code.gson:gson:2.8.8'  (2.9.0 버전은 에러 발생)

import com.google.gson.annotations.SerializedName

->  Unresolved reference: SerializedName 에러 해결

--------------------------------------------------------------------------------------------------------------------------

3. API Interface 생성

New -> Kotlin Class/file

 

 

 

 

→ interface 클릭

 

 

* interface 코드(API.kt)

import retrofit2.http.GET


interface API {
    @GET("users/injekim97")// baseUrl + "user/{유저아이디}"

    fun getUserInfo(

    ): retrofit2.Call<UserInfo>
}

* API 인터페이스를 생성 후 @을 이용하여 HTTP Method인 POST, GET, PUT, DELETE를 설정 

@GET("users/injekim97") : injekim97 자신의 Github 아이디 입력 

 

 

* Call을 불러올때 옆에 retrofit2가 적힌 것을 사용할 것

 

 

---------------------------------------------------------------------------------------------------------------------------------

4. RetrofitBuilder 생성

 

New -> Kotlin Class/file -> object

 

 

* RetrofitBuilder

import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory


object RetrofitBuilder{
    lateinit var api : API

    init{
        val retrofit = Retrofit.Builder()
            .baseUrl("https://api.github.com/")
            .addConverterFactory(GsonConverterFactory.create())
            .build()

        api = retrofit.create(API::class.java)
    }
}

* 고정된 주소인 baseUrl에 https://api.github.com/ 입력 

* .addConverterFactory()

-> GsonConverter를 추가하여 JSON 형식을 DTO Class 형식으로 자동변환 

--------------------------------------------------------------------------------------------------------------------------------

5. API 확인을 위한 XML 작성

 

 

 

 

* activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp"
        android:layout_marginEnd="8dp"
        android:layout_marginBottom="8dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="1.0"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.0">

        <TextView
            android:id="@+id/bio"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="60dp"
            android:layout_marginEnd="60dp"
            android:text="Bio"
            android:textColor="#000000"
            android:textStyle="bold"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.434"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/login"
            app:layout_constraintVertical_bias="0.476" />

        <Button
            android:id="@+id/btn"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="12dp"
            android:layout_marginEnd="18dp"
            android:text="loading"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toEndOf="@+id/imageView"
            app:layout_constraintTop_toTopOf="parent" />

        <TextView
            android:id="@+id/publicRepos"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="60dp"
            android:layout_marginEnd="60dp"
            android:text="repositories"
            android:textColor="#000000"
            android:textStyle="bold"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.433"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/login"
            app:layout_constraintVertical_bias="0.785" />

        <TextView
            android:id="@+id/textView3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="60dp"
            android:layout_marginEnd="60dp"
            android:layout_marginBottom="60dp"
            android:text="Github API USE"
            android:textColor="#000000"
            android:textStyle="bold"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.446"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintVertical_bias="0.045" />

        <ImageView
            android:id="@+id/imageView"
            android:layout_width="0dp"
            android:layout_height="39dp"
            android:layout_marginStart="88dp"
            android:layout_marginEnd="146dp"
            android:layout_marginBottom="60dp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toStartOf="@+id/btn"
            app:layout_constraintHorizontal_bias="1.0"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintVertical_bias="0.025"
            app:srcCompat="@drawable/github" />

        <TextView
            android:id="@+id/login"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="60dp"
            android:layout_marginEnd="60dp"
            android:layout_marginBottom="60dp"
            android:text="User ID"
            android:textColor="#000000"
            android:textStyle="bold"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.434"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/textView3"
            app:layout_constraintVertical_bias="0.149" />

        <TextView
            android:id="@+id/blog"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="60dp"
            android:layout_marginEnd="60dp"
            android:text="Blog Address"
            android:textColor="#000000"
            android:textStyle="bold"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.434"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/login"
            app:layout_constraintVertical_bias="0.217" />

    </androidx.constraintlayout.widget.ConstraintLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

 

 

 

 

-----------------------------------------------------------------------------------------------------------------------------------

6. Activity에 API 호출

 

 

 

 

* MainActivity.kt

import android.os.Bundle
import android.util.Log
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.example.retrofit2.databinding.ActivityMainBinding
import com.google.gson.annotations.SerializedName
import retrofit2.Call
import retrofit2.Response



class MainActivity : AppCompatActivity() {
    val mbinding by lazy { ActivityMainBinding.inflate(layoutInflater) } //뷰 바인딩
    val TAG: String = "로그"
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(mbinding.root)

        mbinding.btn.setOnClickListener {
            Toast.makeText(this, "Get the user's github info ", Toast.LENGTH_SHORT).show()
            RetrofitBuilder.api.getUserInfo().enqueue(object : retrofit2.Callback<UserInfo> {

                //통신 성공
                override fun onResponse(call: Call<UserInfo>, response: Response<UserInfo>) {
                    val userinfo = response.body()!!


                    // ★★★★★ mbinding.id값.text = userinfo?.API 키값 ★★★★★
                    mbinding.login.text = userinfo?.userId
                    mbinding.blog.text = userinfo?.blog
                    mbinding.bio.text = userinfo?.bio
                    mbinding.publicRepos.text = userinfo?.public_repos.toString()

                    Log.d(TAG, "onResponse: 유저아이디: ${userinfo?.userId}, 블로그: ${userinfo?.blog}, 자기소개: ${userinfo?.bio}, 리포지토리 수: ${userinfo?.public_repos}")
                }

                //통신 실패
                override fun onFailure(call: Call<UserInfo>, t: Throwable) {
                    Log.d("error", t.message.toString())
                }

            })

        }
    }

}

-> 뷰바인딩을 사용

* Callback 임포트 : retrofit2

 

 

 

참고 : https://www.notion.so/ViewBindingade69f4fe81c456a908c6e8cda722ce4

 

ViewBinding

ViewBinding 추가

www.notion.so

 

 

-----------------------------------------------------------------------------------------------------------------------------------

<실행 결과>

 

 

 

-> 정상적으로 아이디, blog 주소, 자기소개, 리포지토리 수가 출력된 것을 알 수 있다. 

반응형

댓글