μ•ˆλ“œλ‘œμ΄λ“œ MVVM νŒ¨ν„΄μ„ μ μš©ν•œ Retrofit 2 + OkHttp 5 + RxJava 3 ν”„λ‘œμ νŠΈλ₯Ό κ΅¬μ„±ν•©λ‹ˆλ‹€.


πŸš€ ν”„λ‘œμ νŠΈ ꡬ쑰

bash
λ³΅μ‚¬νŽΈμ§‘
app/
β”œβ”€β”€ data/
β”‚   β”œβ”€β”€ model/            # API 데이터 λͺ¨λΈ (Post.java)
β”‚   β”œβ”€β”€ network/          # Retrofit API μΈν„°νŽ˜μ΄μŠ€ 및 ν΄λΌμ΄μ–ΈνŠΈ (ApiService.java, RetrofitClient.java)
β”‚   β”œβ”€β”€ repository/       # 데이터 λ ˆμ΄μ–΄ (PostRepository.java)
β”œβ”€β”€ ui/
β”‚   β”œβ”€β”€ view/             # UI κ΄€λ ¨ 클래슀 (MainActivity.java, PostAdapter.java)
β”‚   β”œβ”€β”€ viewmodel/        # ViewModel (PostViewModel.java)


πŸ“Œ 1️⃣ build.gradle (Module: app)

Retrofit 2, OkHttp 5, RxJava 3, LiveData 및 ViewModel κ΄€λ ¨ 라이브러리λ₯Ό μΆ”κ°€ν•©λ‹ˆλ‹€.

gradle
λ³΅μ‚¬νŽΈμ§‘
dependencies {
    // 기본 라이브러리
    implementation 'androidx.appcompat:appcompat:1.6.1'
    implementation 'androidx.recyclerview:recyclerview:1.3.1'
    implementation 'androidx.lifecycle:lifecycle-viewmodel:2.6.2'
    implementation 'androidx.lifecycle:lifecycle-livedata:2.6.2'

    // Retrofit 2 + OkHttp 5
    implementation 'com.squareup.retrofit2:retrofit:2.9.0'
    implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
    implementation 'com.squareup.okhttp5:okhttp:5.0.0-alpha.11'
    implementation 'com.squareup.okhttp5:logging-interceptor:5.0.0-alpha.11'

    // RxJava 3 + Retrofit Adapter
    implementation 'io.reactivex.rxjava3:rxjava:3.1.6'
    implementation 'io.reactivex.rxjava3:rxandroid:3.0.2'
    implementation 'com.squareup.retrofit2:adapter-rxjava3:2.9.0'
}


πŸ“Œ 2️⃣ 데이터 λͺ¨λΈ (Post.java)

Retrofit이 API 응닡(JSON)을 μžλ™μœΌλ‘œ Java 객체둜 λ³€ν™˜ν•  수 μžˆλ„λ‘ 데이터 λͺ¨λΈμ„ μƒμ„±ν•©λ‹ˆλ‹€.

java
λ³΅μ‚¬νŽΈμ§‘
package com.example.retrofitexample.data.model;

import com.google.gson.annotations.SerializedName;

public class Post {
    @SerializedName("userId")
    private int userId;

    @SerializedName("id")
    private int id;

    @SerializedName("title")
    private String title;

    @SerializedName("body")
    private String body;

    public int getUserId() { return userId; }
    public int getId() { return id; }
    public String getTitle() { return title; }
    public String getBody() { return body; }
}


πŸ“Œ 3️⃣ Retrofit API μ„œλΉ„μŠ€ (ApiService.java)

Retrofitμ—μ„œ μ‚¬μš©ν•  API μš”μ²­μ„ μ •μ˜ν•©λ‹ˆλ‹€.

java
λ³΅μ‚¬νŽΈμ§‘
package com.example.retrofitexample.data.network;

import com.example.retrofitexample.data.model.Post;
import java.util.List;
import io.reactivex.rxjava3.core.Single;
import retrofit2.http.GET;

public interface ApiService {
    @GET("posts")
    Single<List<Post>> getPosts();
}


πŸ“Œ 4️⃣ Retrofit & OkHttp 5 ν΄λΌμ΄μ–ΈνŠΈ (RetrofitClient.java)

Retrofitκ³Ό OkHttp 5λ₯Ό μ„€μ •ν•©λ‹ˆλ‹€.

java
λ³΅μ‚¬νŽΈμ§‘
package com.example.retrofitexample.data.network;

import java.util.concurrent.TimeUnit;
import io.reactivex.rxjava3.schedulers.Schedulers;
import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava3.RxJava3CallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;

public class RetrofitClient {
    private static Retrofit retrofit = null;

    public static Retrofit getClient() {
        if (retrofit == null) {
            HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor();
            loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);

            OkHttpClient client = new OkHttpClient.Builder()
                    .connectTimeout(30, TimeUnit.SECONDS)
                    .readTimeout(30, TimeUnit.SECONDS)
                    .writeTimeout(30, TimeUnit.SECONDS)
                    .addInterceptor(loggingInterceptor)
                    .build();

            retrofit = new Retrofit.Builder()
                    .baseUrl("<https://jsonplaceholder.typicode.com/>")
                    .client(client)
                    .addConverterFactory(GsonConverterFactory.create())
                    .addCallAdapterFactory(RxJava3CallAdapterFactory.createWithScheduler(Schedulers.io()))
                    .build();
        }
        return retrofit;
    }
}