안드로이드 네이티브 앱에서 API와의 통신을 구현하기 위해 다음 단계를 수행했습니다.

app/build.gradle 파일에 Retrofit 라이브러리 의존성을 추가AndroidManifest.xml 파일에 인터넷 권한을 추가// app/build.gradle
dependencies {
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
}
<!-- AndroidManifest.xml -->
<uses-permission android:name="android.permission.INTERNET"/>
API 요청과 응답을 처리하기 위한 데이터 클래스를 정의합니다.
// UserSignUpRequest.kt
data class UserSignUpRequest(
val email: String,
val password: String,
val name: String,
val phoneNumber: String
)
// ResultResponseVoid.kt
data class ResultResponseVoid(
val status: String,
val statusCode: List<Int>,
val message: String,
val data: Any?
)
Retrofit을 통해 사용할 API 메서드를 정의하는 인터페이스를 생성합니다.
// ApiService.kt
package com.example.seureureuk.network
import ...
interface ApiService {
@PUT("participant/{participantId}")
suspend fun confirmRequestedSettlement(@Path("participantId") participantId: Int): Response<Void>
@GET("settlements")
suspend fun getRequestedSettlement(): Response<RequestedSettlementResponseData>
@GET("settlements/{settlementId}")
suspend fun getSettlementDetail(@Path("settlementId") settlementId: Int): Response<SettlementDetailResponseData>
@POST("settlements/{settlementId}")
suspend fun executeSettlementProcess(@Path("settlementId") settlementId: Int): Response<SettlementCompletedResponseData>
// id: settlementId
@GET("settlements/{id}/participants")
suspend fun getSettlementParticipants(@Path("id") id: Int): Response<SettlementParticipantResponseData>
@POST("settlements/{groupId}/request")
suspend fun addSettlement(@Path("groupId") groupId: Int, @Body request: SettlementAddRequest): Response<SettlementAddResponseData>
@POST("groups/entrance")
suspend fun enterGroupWithInviteCode(@Body request: GroupEntranceRequest): Response<GroupEntranceResponseData>
@POST("groups/{groupId}/invite")
fun createInviteCode(@Path("groupId") groupId: Int): Call<GroupInviteResponseData>
@POST("groups")
suspend fun createGroup(@Body request: GroupCreateRequest): Response<GroupCreateResponseData>
@GET("groups/{groupId}/members")
suspend fun getGroupMembers(@Path("groupId") groupId: Int): Response<GroupMemberResponseData>
@GET("groups/{groupId}/settlements")
suspend fun getGroupSettlements(@Path("groupId") groupId: Int): Response<GroupSettlementResponseData>
@GET("groups")
fun getAllGroups(): Call<GroupInfoResponseList>
@POST("users/register")
fun signUpUser(@Body request: UserSignUpRequest): Call<ResultResponseVoid>
@POST("users/auth/login")
fun loginUser(@Body request: UserLoginRequest): Call<ResultResponseUserLoginResponse>
@POST("accounts/register")
fun registerAccount(@Body request: AccountRegisterRequest): Call<ResultResponseVoid>
@GET("points")
fun getPointInfo(): Call<ResultResponsePointInfoResponse>
@GET("accounts")
fun getAccounts(): Call<ResultResponseListAccountResponse>
@POST("points")
fun convertPoints(@Body request: PointConversionRequest): Call<ResultResponsePointConversionResponse>
@DELETE("accounts/{accountId}/delete")
fun deleteAccount(@Path("accountId") accountId: Long): Call<ResultResponseVoid>
@POST("points/exchange")
fun convertPointsExchange(@Body request: PointConversionRequest): Call<ResultResponsePointConversionResponse>
@GET("users")
fun getUserMyPageInfo(): Call<ResultResponseUserMyPageResponse>
}
Retrofit 인스턴스를 생성하여 API 서비스와 연결합니다.
// RetrofitInstance.kt
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
object RetrofitInstance {
private const val BASE_URL = "http://172.191.5.168/api/"
val api: ApiService by lazy {
Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build()
.create(ApiService::class.java)
}
}
// MyPageActivity.kt
package com.example.seureureuk
import ...
class MyPageActivity : AppCompatActivity() {
private lateinit var nameTextView: TextView
private lateinit var balanceTextView: TextView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_my_page)
nameTextView = findViewById(R.id.user_name)
balanceTextView = findViewById(R.id.balance_amount)
loadUserInfo()
loadUserPoints()
}
//유저 정보 불러오기 위해 API 호출
private fun loadUserInfo() {
val apiService = RetrofitInstance.api
apiService.getUserMyPageInfo().enqueue(object : Callback<ResultResponseUserMyPageResponse> {
override fun onResponse(call: Call<ResultResponseUserMyPageResponse>, response: Response<ResultResponseUserMyPageResponse>) {
if (response.isSuccessful) {
val userInfo = response.body()?.data
if (userInfo != null) {
nameTextView.text = userInfo.name
Log.d("MyPageActivity","$userInfo.name")
} else {
Toast.makeText(this@MyPageActivity, "사용자 정보를 불러올 수 없습니다.", Toast.LENGTH_SHORT).show()
}
} else {
Log.e("MyPageActivity", "Failed to load user info: ${response.errorBody()?.string()}")
}
}
override fun onFailure(call: Call<ResultResponseUserMyPageResponse>, t: Throwable) {
Log.e("MyPageActivity", "Error: ${t.message}")
}
})
}
//포인트 정보 불러오기 위해 API 호출
private fun loadUserPoints() {
val apiService = RetrofitInstance.api
apiService.getPointInfo().enqueue(object : Callback<ResultResponsePointInfoResponse> {
override fun onResponse(call: Call<ResultResponsePointInfoResponse>, response: Response<ResultResponsePointInfoResponse>) {
if (response.isSuccessful) {
val pointInfo = response.body()?.data
if (pointInfo != null) {
val pointValue = pointInfo.point
val formattedPoint = NumberFormat.getNumberInstance(Locale.KOREA).format(pointValue) + "원"
balanceTextView.text = formattedPoint
Log.d("MyPageActivity", "$pointInfo")
} else {
Toast.makeText(this@MyPageActivity, "포인트 정보를 불러올 수 없습니다.", Toast.LENGTH_SHORT).show()
}
} else {
val errorBody = response.errorBody()?.string() ?: "Unknown error"
Log.e("MyPageActivity", "Failed to load points info: $errorBody")
}
}
override fun onFailure(call: Call<ResultResponsePointInfoResponse>, t: Throwable) {
Log.e("MyPageActivity", "Network error: ${t.message}")
}
})
}
}
초기 세팅 후, !! 추가로 API 연동할 때는 !!
1.Request,Response데이터 클래스 정의 ⚠️ Response에서 statusCode Int로 하기 ⚠️
2.APiService에 API 호출 추가
3. Retrofit 인스턴스 업데이트
4. Activity에서 API 호출