사악미소
현대마법의 공방
사악미소
전체 방문자
오늘
어제
  • 분류 전체보기
    • Document
    • JavaScript
    • jQuery
    • Spring Web
      • Spring Framework
      • Spring Boot
    • Android
      • Java Code
      • Setting
    • iOS
      • Swift Code
      • Setting
    • PHP
      • Code
      • Setting
    • AWS
    • LINUX
      • Rocky Linux
      • CentOS
    • Node.js
    • Developer Tool
    • GIT
    • MAC
    • Scraping Document
    • MariaDB
    • WYSIWYG
    • Scouter
    • Docker
    • Planning
    • 용어정리
반응형

인기 글

최근 댓글

Programmer 사악미소.
사악미소

사악미소의 현대마법의 공방

[Android] Retrofit2를 사용한 API 통신 설정 및 Data 송수신
Android/Java Code

[Android] Retrofit2를 사용한 API 통신 설정 및 Data 송수신

2023. 2. 7. 11:27
728x90

 

※ 해당 포스팅은 아래 Rest API를 사용하여 작성하였습니다.

 

Reqres - A hosted REST-API ready to respond to your AJAX requests

Native JavaScript If you've already got your own application entities, ie. "products", you can send them in the endpoint URL, like so: var xhr = new XMLHttpRequest(); xhr.open("GET", "https://reqres.in/api/products/3", true); xhr.onload = function(){ conso

reqres.in

 


 

# Retrofit2 설정 및 송수신 Code 작성

 

1) Manifest 설정

AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">

    <!-- INTERNET 퍼미션 추가 -->
    <uses-permission android:name="android.permission.INTERNET"></uses-permission>

    ~~ 이 하 생 략 ~~

</manifest>
더보기
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">

    <!-- INTERNET 퍼미션 추가 -->
    <uses-permission android:name="android.permission.INTERNET"></uses-permission>

    <application
        android:allowBackup="true"
        android:dataExtractionRules="@xml/data_extraction_rules"
        android:fullBackupContent="@xml/backup_rules"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.Retrofit2"
        tools:targetApi="31">
        <activity
            android:name=".MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>

            <meta-data
                android:name="android.app.lib_name"
                android:value="" />
        </activity>
    </application>

</manifest>

 

 


 

2) Retrofit2 라이브러리 추가( build.gradle 설정 )

build.gradle
plugins {
    id 'com.android.application'
}

android {
    
    ~~ 이하 생 략 ~~

    // viewBinding 사용
    buildFeatures {
        viewBinding = true
    }
}

dependencies {

    ~~ 이하 생 략 ~~

    // Retrofit2
    implementation 'com.squareup.retrofit2:retrofit:2.9.0'
    implementation 'com.squareup.retrofit2:converter-gson:2.9.0'

    // Gson
    implementation 'com.google.code.gson:gson:2.10.1'

    ~~ 이하 생 략 ~~
}
더보기
plugins {
    id 'com.android.application'
}

android {
    namespace 'org.retrofit.example'
    compileSdk 33

    defaultConfig {
        applicationId "org.retrofit.example"
        minSdk 21
        targetSdk 33
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }

    buildFeatures {
        viewBinding = true
    }
}

dependencies {

    implementation 'androidx.appcompat:appcompat:1.6.0'
    implementation 'com.google.android.material:material:1.8.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.1.4'

    // Retrofit2
    implementation 'com.squareup.retrofit2:retrofit:2.9.0'
    implementation 'com.squareup.retrofit2:converter-gson:2.9.0'

    // Gson
    implementation 'com.google.code.gson:gson:2.10.1'

    testImplementation 'junit:junit:4.13.2'
    androidTestImplementation 'androidx.test.ext:junit:1.1.5'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
}

 

 


 

3) Retrofit2 데이터 송수신 Code( 제목 변경 할것 )

 

① RetrofitFactory Class 생성

RetrofitFactory.java
package org.retrofit.example.network;

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

public class RetrofitFactory {

    private static String BASE_URL = "https://reqres.in/";

    public static RetrofitService create() {

        // Retrofit 객체 생성
        Retrofit retrofit = new Retrofit.Builder()
            .baseUrl(BASE_URL)
            .addConverterFactory(GsonConverterFactory.create())
            .build();

        return retrofit.create(RetrofitService.class);
    }
}

 

 


 

② RetrofitService Interface 생성

RetrofitService.java
package org.retrofit.example.network;

import org.retrofit.example.model.ModelUserCreate;
import org.retrofit.example.model.ModelUserList;
import org.retrofit.example.model.ModelUserSingle;

import retrofit2.Call;
import retrofit2.http.Field;
import retrofit2.http.FormUrlEncoded;
import retrofit2.http.GET;
import retrofit2.http.POST;
import retrofit2.http.Path;
import retrofit2.http.Query;

public interface RetrofitService {

    /**
     * @brief "API - GET SINGLE RESOURCE"
     */
    @GET("api/users/{id}")
    Call<ModelUserSingle> doGetUserInfo(
        @Path("id") int id
    );

    /**
     * @brief "API - GET LIST RESOURCE"
     */
    @GET("api/users")
    Call<ModelUserList> doGetUserList(
        @Query("page") int page
    );

    /**
     * @brief "API - POST Login Access"
     */
    @FormUrlEncoded
    @POST("api/users/edit")
    Call<ModelUserCreate> doPostUserCreate(
          @Field("first_name") String first_name
        , @Field("last_name") String last_name
        , @Field("name") String name
    );
}

 

 


 

 

4) Data Model 생성

 

① 사용자 정보 Model Class 생성

ModelUser.java
package org.retrofit.example.model;

import com.google.gson.annotations.SerializedName;

public class ModelUser {

    @SerializedName("id")
    private int userId;

    @SerializedName("first_name")
    private String firstName;

    @SerializedName("last_name")
    private String lastName;

    private String avatar;

    public int getUserId() { return userId; }

    public void setUserId(int userId) { this.userId = userId; }

    public String getFirstName() { return firstName; }

    public void setFirstName(String firstName) { this.firstName = firstName; }

    public String getLastName() { return lastName; }

    public void setLastName(String lastName) { this.lastName = lastName; }

    public String getAvatar() { return avatar; }

    public void setAvatar(String avatar) { this.avatar = avatar; }

    @Override
    public String toString() {
        return "ModelUser {" +
            "\n  userId=" + userId +
            "\n, firstName=\"" + firstName + "\"" +
            "\n, lastName=\"" + lastName + "\"" +
            "\n, avatar=\"" + avatar + "\"" +
        "\n}\n";
    }
}

 

 


 

② 사용자 단일 조회 Model Class 생성

ModelUserSingle.java
package org.retrofit.example.model;

public class ModelUserSingle {

    private ModelUser data;

    public ModelUser getData() { return data; }

    public void setData(ModelUser data) { this.data = data; }

    @Override
    public String toString() {
        return "ModelUserSingle {\ndata=" + data.toString() + "\n}";
    }
}

 


 

③ 사용자 목록 조회 Model Class 생성

ModelUserList.java
package org.retrofit.example.model;

import com.google.gson.annotations.SerializedName;

import java.util.List;

public class ModelUserList {

    private int page;

    @SerializedName("per_page")
    private int perPage;

    private int total;

    @SerializedName("total_pages")
    private int totalPages;

    private List<ModelUser> data;

    public int getPage() { return page; }

    public void setPage(int page) { this.page = page; }

    public int getPerPage() { return perPage; }

    public void setPerPage(int perPage) { this.perPage = perPage; }

    public int getTotal() { return total; }

    public void setTotal(int total) { this.total = total; }

    public int getTotalPages() { return totalPages; }

    public void setTotalPages(int totalPages) { this.totalPages = totalPages; }

    public List<ModelUser> getData() { return data; }

    public void setData(List<ModelUser> data) { this.data = data; }

    @Override
    public String toString() {
        return "ModelUserList {" +
            "\n  page=" + page +
            "\n, perPage=" + perPage +
            "\n, total=" + total +
            "\n, totalPages=" + totalPages +
            "\n, data=" + data.toString() +
        "\n}";
    }
}

 


 

④ 사용자 생성 Model Class 생성

ModelUserCreate.java
package org.retrofit.example.model;

public class ModelUserCreate {

    private String id;
    private String createdAt;

    public String getId() { return id; }

    public void setId(String id) { this.id = id; }

    public String getCreatedAt() { return createdAt; }

    public void setCreatedAt(String createdAt) { this.createdAt = createdAt; }

    @Override
    public String toString() {
        return "ModelUserCreate {" +
            "\n  id=\"" + id + "\"" +
            "\n, createdAt=\"" + createdAt + "\"" +
        "\n}";
    }
}

 


 

 

5) LogMsg 설정

 

프로젝트에 utility라는 패키지를 추가한다.

 

 

패키지가 생성되면 LogMsgOutput 클래스 파일을 생성한다.

 

 

LogMsgOutput 클래스 파일 코드는 아래와 같다.

 

 

LogMsgOutput.java
package org.retrofit.example.utility;

import android.content.Context;
import android.util.Log;

public class LogMsgOutput {

    private static String lineOut() {
        int level = 4;
        StackTraceElement[] traces;
        traces = Thread.currentThread().getStackTrace();
        return ("at " + traces[level] + " ");
    }

    private static String buildLogMsg(String message) {
        StackTraceElement ste = Thread.currentThread().getStackTrace()[4];
        StringBuffer sb = new StringBuffer();
        sb.append(" [ ");
        sb.append(ste.getFileName().replace(".java", ""));
        sb.append(" :: ");
        sb.append(ste.getMethodName());
        sb.append(" ] ");
        sb.append(message);
        return sb.toString();
    }

    public static void logPrintOut(Context context, String logMsg) {
        //resources.getSystem().getString(R.string.execMode);
        if("debug".equals("debug") == true) {
            Log.d("MSG:::By-LogUtil:::", buildLogMsg(logMsg + " :: " + lineOut()));
        }
    }
}

 


 

6) Activity 화면 생성

activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <GridLayout
        android:id="@+id/gridLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:columnCount="3"
        android:orientation="horizontal">

        <Button
            android:id="@+id/btn_user_info"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_row="0"
            android:layout_column="0"
            android:layout_margin="2dp"
            android:text="사용자 조회">
        </Button>

        <Button
            android:id="@+id/btn_user_list"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_row="0"
            android:layout_column="1"
            android:layout_margin="2dp"
            android:text="사용자 리스트">
        </Button>

        <Button
            android:id="@+id/btn_user_create"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_row="0"
            android:layout_column="2"
            android:layout_margin="2dp"
            android:text="사용자 생성">
        </Button>

    </GridLayout>

    <TextView
        android:id="@+id/text_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="">
    </TextView>

</LinearLayout>

 

 


 

 

7) 실행 Activity Class 생성

MainActivity.java
package org.retrofit.example;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.view.View;
import android.widget.TextView;

import com.google.gson.Gson;

import org.retrofit.example.databinding.ActivityMainBinding;
import org.retrofit.example.model.ModelUserCreate;
import org.retrofit.example.model.ModelUserList;
import org.retrofit.example.model.ModelUserSingle;
import org.retrofit.example.network.RetrofitFactory;
import org.retrofit.example.network.RetrofitService;
import org.retrofit.example.utility.LogMsgOutput;

import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private RetrofitService retrofitService = RetrofitFactory.create();

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        ActivityMainBinding binding = ActivityMainBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());

        // OnClickListener interface를 implements하여 메서드 구현
        binding.btnUserInfo.setOnClickListener(this);
        binding.btnUserList.setOnClickListener(this);
        binding.btnUserCreate.setOnClickListener(this);
    }

    @Override
    public void onClick(View view) {

        switch(view.getId()) {
            case R.id.btn_user_info :
                doGetUserSingle();
                break;
            case R.id.btn_user_list :
                doGetUserList();
                break;
            case R.id.btn_user_create :
                doPostUserCreate();
                break;
            default:
                break;
        }
    }

    private void doGetUserSingle() {
        retrofitService.doGetUserInfo(
                10
        ).enqueue(new Callback<ModelUserSingle>() {

            @Override
            public void onResponse(Call<ModelUserSingle> call, Response<ModelUserSingle> response) {
                if(response.isSuccessful() == true) {

                    ModelUserSingle responseData = response.body();
                    LogMsgOutput.logPrintOut(getApplicationContext(), "통신성공");
                    LogMsgOutput.logPrintOut(getApplicationContext(), "responseData : " + new Gson().toJson(responseData));

                    TextView textView = (TextView)findViewById(R.id.text_view);
                    textView.setText(responseData.toString());
                }
            }

            @Override
            public void onFailure(Call<ModelUserSingle> call, Throwable t) {
                LogMsgOutput.logPrintOut(getApplicationContext(), "통신실패");
                LogMsgOutput.logPrintOut(getApplicationContext(), "Throwable : " + t.getMessage());
                call.cancel();
            }
        });
    }

    private void doGetUserList() {
        retrofitService.doGetUserList(
                2
        ).enqueue(new Callback<ModelUserList>() {

            @Override
            public void onResponse(Call<ModelUserList> call, Response<ModelUserList> response) {
                if(response.isSuccessful() == true) {

                    ModelUserList responseData = response.body();
                    LogMsgOutput.logPrintOut(getApplicationContext(), "통신성공");
                    LogMsgOutput.logPrintOut(getApplicationContext(), "responseData : " + new Gson().toJson(responseData));

                    TextView textView = (TextView)findViewById(R.id.text_view);
                    textView.setText(responseData.toString());
                }
            }

            @Override
            public void onFailure(Call<ModelUserList> call, Throwable t) {
                LogMsgOutput.logPrintOut(getApplicationContext(), "통신실패");
                LogMsgOutput.logPrintOut(getApplicationContext(), "Throwable : " + t.getMessage());
                call.cancel();
            }
        });
    }

    private void doPostUserCreate() {
        retrofitService.doPostUserCreate(
              "first_name"
            , "last_name"
            , "full_name"
        ).enqueue(new Callback<ModelUserCreate>() {

            @Override
            public void onResponse(Call<ModelUserCreate> call, Response<ModelUserCreate> response) {
                if(response.isSuccessful() == true) {

                    ModelUserCreate responseData = response.body();
                    LogMsgOutput.logPrintOut(getApplicationContext(), "통신성공");
                    LogMsgOutput.logPrintOut(getApplicationContext(), "responseData : " + new Gson().toJson(responseData));

                    TextView textView = (TextView)findViewById(R.id.text_view);
                    textView.setText(responseData.toString());
                }
            }

            @Override
            public void onFailure(Call<ModelUserCreate> call, Throwable t) {
                LogMsgOutput.logPrintOut(getApplicationContext(), "통신실패");
                LogMsgOutput.logPrintOut(getApplicationContext(), "Throwable : " + t.getMessage());
                call.cancel();
            }
        });
    }
}

 

 


 

 

# Application 실행 결과

 

 

 

 

728x90

'Android > Java Code' 카테고리의 다른 글

[Android] App 실행시 Intro 화면 제작  (0) 2024.07.29
[Android] WebView를 이용한 Hybrid App 만들기  (0) 2024.07.29
[Android] Keyboard위에 Edit Text 올리기  (0) 2023.02.06
[Android] 출력 위치를 확인하는 Custom Log Message 제작  (0) 2023.02.02
[Android] FCM 메시지 송수신 Application 제작  (0) 2023.02.01
    'Android/Java Code' 카테고리의 다른 글
    • [Android] App 실행시 Intro 화면 제작
    • [Android] WebView를 이용한 Hybrid App 만들기
    • [Android] Keyboard위에 Edit Text 올리기
    • [Android] 출력 위치를 확인하는 Custom Log Message 제작
    사악미소
    사악미소

    티스토리툴바