본문 바로가기
Android

Retrofit을 사용하여 데이터를 가져와 화면에 나타내기

by 안솝우화 2021. 4. 14.
반응형

2021.04.10 - [Android Studio/Retrofit] - Json 데이터 클래스 생성

 

Json 데이터 클래스 생성

json객체를 앱에서 변환을 해줘야 합니다 변환하는 방법은 수동적인 방법도 있지만 매우 비효율적이고 오류가 발생하기 쉽습니다. 때문에 정확하고 효율적인 JSON To Kotlin Class 를 사용합니다 안드

asuhdevstory.tistory.com

이전글에서 데이터 클래스를 생성했었습니다(이전글과 설명을 이어서 하도록 하겠습니다)

시작하기 앞서서 Gradle(Module)에 추가해줍니다(버전은 달라질수 있으니 공식문서등을 참고해 주세요)

square.github.io/retrofit/

 

Retrofit

A type-safe HTTP client for Android and Java

square.github.io

github.com/Kotlin/kotlinx.coroutines

 

Kotlin/kotlinx.coroutines

Library support for Kotlin coroutines . Contribute to Kotlin/kotlinx.coroutines development by creating an account on GitHub.

github.com

github.com/square/okhttp/tree/master/okhttp-logging-interceptor

 

square/okhttp

Square’s meticulous HTTP client for the JVM, Android, and GraalVM. - square/okhttp

github.com

developer.android.com/jetpack/androidx/releases/lifecycle?hl=ko

 

수명 주기  |  Android 개발자  |  Android Developers

Lifecycle 수명 주기 인식 구성요소는 활동 및 프래그먼트와 같은 다른 구성요소의 수명 주기 상태 변경에 따라 작업을 실행합니다. 이러한 구성요소를 사용하면 잘 구성된 경량의 코드를 만들어

developer.android.com

  def coroutines_version = "1.4.3"
    def retrofit_version = "2.9.0"
    def lifecycle_version = "2.3.0"  
  
  //retrofit
    implementation "com.squareup.retrofit2:retrofit:$retrofit_version"
    implementation "com.squareup.retrofit2:converter-gson:$retrofit_version"

    //coroutines
    implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines_version"
    //코루틴 안드로이드 의존성 추가
    implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutines_version"

    // ViewModel
    implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version"
    // LiveData
    implementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version"
    // Annotation processor(위에 'kotlin-kapt' 플러그인 추가)
    kapt "androidx.lifecycle:lifecycle-compiler:$lifecycle_version"


    //okhttp
    implementation "com.squareup.okhttp3:logging-interceptor:4.9.1"

그리고 Manifests에서 인터넷 사용권한등을 설정해 줍니다

    <!-- 인터넷 사용권한 -->
    <uses-permission android:name="android.permission.INTERNET" /> 
    <!-- 네트워크 상태 액세스 권한 -->
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <!-- Wi-Fi 상태 액세스 권한 -->
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />

 

그 다음 AlbumService라는 인터페이스 파일 한개를 생성해줍니다

 

AlbumService.kt

import retrofit2.Response
import retrofit2.http.GET

interface AlbumService {

    //레트로핏 인스턴스 class를 만들때는 기본url을 추가하고
    // 이 URL은 url 끝부분만 넣는다
    //예 ) http://jsonplaceholder.typicode.com/albums
    // http://jsonplaceholder.typicode.com (baseurl)
    // /albums (endurl)
    @GET("/albums")

    //코루틴을 사용할꺼기 때문에 suspend fun 사용
    //retrofit은 항상 Refrofit response객체로 결과를 제공,
    // 때문에 반환값을 Response<Albums>
    suspend fun getAlbums() : Response<Albums>
}

 

그 다음으로는 인스턴스 클래스를 생성해 줍니다

 

RetrofitInstance.kt

import com.google.gson.GsonBuilder
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory

//레트로핏 인스턴스 클래스
class RetrofitInstance {
    //companion object를 추가하는 이유는 companion object 개체는 클래스가 처음 로드 될때 초기화 됩니다
    //companion object 객체 내부에 레트로핏 인스턴스를 만들면 클래스 이름을 사용하여 쉽게 사용가능
    companion object{
        //앞에서 한 baseurl과 endurl 설명 참조
        //http를 사용하면 안되고 https를 사용해야함(안드로이드 9.0 파이에서는 https를 사용하도록 강제)
        val BASE_URL = "https://jsonplaceholder.typicode.com/"

        fun getRetrofitInstance():Retrofit{
            return Retrofit.Builder()
                .baseUrl(BASE_URL)
                //GSON 변환기 팩토리를 사용하여 JSON을 Kotlin으로 변환합니다
                .addConverterFactory(GsonConverterFactory.create(GsonBuilder().create()))
                //마지막으로 빌드
                .build()
        }
    }
}

 

메인액티비티 xml로 가서 스크롤뷰와 textview를 추가해 줍니다

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<layout>

    <ScrollView 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">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">

            <TextView
                android:id="@+id/text_view"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:textSize="10dp" />
        </LinearLayout>

    </ScrollView>

</layout>

참고로 Databinding을 사용하였습니다

데이터바인딩 사용방법에 대해 궁금하시면 확인해주세요

2021.03.25 - [Android Studio/Jetpack] - Data Binding 이란?

 

Data Binding 이란?

Data Binding 의 작동 방식 레이아웃의 각 보기에 대한 참조를 포함하는 바인딩 개체를 만듭니다. 바인딩 개체가 생성되면 바인딩 개체를 통해 앱의 모든 구성 요소가 보기 및 기타 데이터에 액세스

asuhdevstory.tistory.com

 MainActivity.kt

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import androidx.databinding.DataBindingUtil
import androidx.lifecycle.LiveData
import androidx.lifecycle.Observer
import androidx.lifecycle.liveData
import com.example.retrofit.databinding.ActivityMainBinding
import retrofit2.Response
import retrofit2.create

class MainActivity : AppCompatActivity() {
    lateinit var binding : ActivityMainBinding
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = DataBindingUtil.setContentView(this,R.layout.activity_main)
        val retService = RetrofitInstance
                .getRetrofitInstance()
                .create(AlbumService::class.java)
        val responseLiveData : LiveData<Response<Albums>> = liveData {
            //인터페이스 사용하여 응답 개체를 가져옴
            val response = retService.getAlbums()
            //방출
            emit(response)
        }
        responseLiveData.observe(this, Observer {
            val albumsList = it.body()?.listIterator()
            if(albumsList!= null){
                while (albumsList.hasNext()){
                    val albumsItem = albumsList.next()
                    Log.i("MYTAG",albumsItem.title)
                    val result = " "+"Album Title : ${albumsItem.title}"+"\n"+
                                " "+"Album id : ${albumsItem.id}"+"\n"+
                                " "+"User id : ${albumsItem.userId}"+"\n\n\n"
                    binding.textView.append(result)
                }
            }
        })

    }
}

 이제 실행해 봅니다

 

 

결과가 잘 나오는것을 확인하실수 있습니다

 

여기서 쿼리 매개 변수를 사용해 보겠습니다, AlbumService.kt 인터페이스에 코드를 추가해 줍니다

AlbumService.kt

    @GET("/albums")
    suspend fun getSortedAlbums(@Query("userId") userId : Int) : Response<Albums>

 그리고 MainActivity.kt로 가서 응답 개체를 가져오는 부분을 수정해 줍니다

val response = retService.getSortedAlbums(4)

MainActivity.kt

class MainActivity : AppCompatActivity() {
    lateinit var binding : ActivityMainBinding
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = DataBindingUtil.setContentView(this,R.layout.activity_main)
        val retService = RetrofitInstance
                .getRetrofitInstance()
                .create(AlbumService::class.java)
        val responseLiveData : LiveData<Response<Albums>> = liveData {
            //인터페이스 사용하여 응답 개체를 가져옴
            val response = retService.getSortedAlbums(4)
            //방출
            emit(response)
        }
        responseLiveData.observe(this, Observer {
            val albumsList = it.body()?.listIterator()
            if(albumsList!= null){
                while (albumsList.hasNext()){
                    val albumsItem = albumsList.next()
                    Log.i("MYTAG",albumsItem.title)
                    val result = " "+"Album Title : ${albumsItem.title}"+"\n"+
                                " "+"Album id : ${albumsItem.id}"+"\n"+
                                " "+"User id : ${albumsItem.userId}"+"\n\n\n"
                    binding.textView.append(result)
                }
            }
        })

    }
}

실행 해 봅니다

 

짠!! 이렇게 User id가 4에 해당하는 내용만 나오게 됩니다

반응형

'Android' 카테고리의 다른 글

Notification의 사용방법  (0) 2021.05.06
Okhttp란?  (0) 2021.04.15
Json 데이터 클래스 생성  (0) 2021.04.10
rtdb에서 값을 가져오지 못하는 오류  (0) 2021.04.07
RecyclerView 란?  (0) 2021.04.03