-
안드로이드 스튜디오 RetrofitAndroid Studio 2023. 8. 10. 21:17728x90
Retrofit 이란?
통신 라이브러리 중 가장 많이 사용되는 대표적인 라이브러이 입니다.
REST API 통신을 위해 구현되었으며, Squareup사의 OkHttp 라이브러리의 상위 구현체 입니다.
Retrofit은 OkHttp를 네트워크 계층으로 활용하고 그 위에 구축되어 있습니다.
AsyncTask 없이 Background Thread 실행 -> Callback을 통해 Main Thread에서 UI 업데이트
Retrofit 장점
1. 빠른 성능 : Asynctask를 사용하지 않고 자체적인 비동기 실행과 스레드 관리를 통해 속도가 많이 개선
2. 간단한 구현 : Retrofit에서는 Request, Response 설정 등 반복적인 작업을 라이브러리에서 넘겨서 처리하므로 작업량이 줄어들고 사용하기 굉장히 편리합니다. 또한 동기 / 비동기에 대해서 쉽게 구현을 할 수 있습니다.
3. 가독성 : 애노테이션 사용으로 코드의 가독성이 뛰어나며, 직관적이 설계가 가능합니다.
안드로이드 스튜디오에서 사용하기 위한 셋팅으로는 하기와 같습니다.
1. Manifest 에 인터넷 권한을 허용하는 코드를 작성합니다.
<uses-permission android:name="android.permission.INTERNET" />
2. Gradle 의존성을 추가 합니다.
// Retrofit 라이브러리 implementation 'com.squareup.retrofit2:retrofit:2.9.0' // Gson 변환기 라이브러리 implementation 'com.squareup.retrofit2:converter-gson:2.9.0' // Scalars 변환기 라이브러리 implementation 'com.squareup.retrofit2:converter-scalars:2.9.0'
Gson Converter : JSON 타입의 응답 결과를 객체로 변환해주는 Converter
Scalars Converter - 응답결과를 String자체로 받아서 보여주는 Converter
Moshi Converter Jackson Converter등 이 외의 여러 Converter가 있습니다.
3. REST API로 받아올 데이터를 변환하여 매핑할 데이터 클래스 선언
class Repository : ArrayList<RepositoryItem>() data class License( val key: String, val name: String, val node_id: String, val spdx_id: String, val url: String ) data class Owner( val avatar_url: String, val events_url: String, val followers_url: String, val following_url: String, val gists_url: String, val gravatar_id: String, val html_url: String, val id: Int, val login: String, val node_id: String, val organizations_url: String, val received_events_url: String, val repos_url: String, val site_admin: Boolean, val starred_url: String, val subscriptions_url: String, val type: String, val url: String ) package com.test.retrofitstudy data class RepositoryItem( val allow_forking: Boolean, val archive_url: String, val archived: Boolean, val assignees_url: String, val blobs_url: String, val branches_url: String, val clone_url: String, val collaborators_url: String, val comments_url: String, val commits_url: String, val compare_url: String, val contents_url: String, val contributors_url: String, val created_at: String, val default_branch: String, val deployments_url: String, val description: String, val disabled: Boolean, val downloads_url: String, val events_url: String, val fork: Boolean, val forks: Int, val forks_count: Int, val forks_url: String, val full_name: String, val git_commits_url: String, val git_refs_url: String, val git_tags_url: String, val git_url: String, val has_discussions: Boolean, val has_downloads: Boolean, val has_issues: Boolean, val has_pages: Boolean, val has_projects: Boolean, val has_wiki: Boolean, val homepage: String, val hooks_url: String, val html_url: String, val id: Int, val is_template: Boolean, val issue_comment_url: String, val issue_events_url: String, val issues_url: String, val keys_url: String, val labels_url: String, val language: String, val languages_url: String, val license: License, val merges_url: String, val milestones_url: String, val mirror_url: Any, val name: String, val node_id: String, val notifications_url: String, val open_issues: Int, val open_issues_count: Int, val owner: Owner, val `private`: Boolean, val pulls_url: String, val pushed_at: String, val releases_url: String, val size: Int, val ssh_url: String, val stargazers_count: Int, val stargazers_url: String, val statuses_url: String, val subscribers_url: String, val subscription_url: String, val svn_url: String, val tags_url: String, val teams_url: String, val topics: List<String>, val trees_url: String, val updated_at: String, val url: String, val visibility: String, val watchers: Int, val watchers_count: Int, val web_commit_signoff_required: Boolean )
interface GithubService { @GET("users/Kotlin/repos") fun users(): Call<Repository> }
@GET("users/Kotlin/repos") - 요청메소드 GET, baseUrl에 연결될 EndPoint 'posts/{post}
반환타입 Call<Repository> - Call은 응답이 왔을때 Callback으로 불려질 타입
PostResult - 요청GET에 대한 응답데이터를 받아서 DTO 객체화할 클래스 타입 지정
메소드명 "users" - 자유롭게 설정, 통신에 영향 xRetrofit.Build를 통해 Retrofit 인스턴스 생성
- baseUrl, Converter, Client 설정 부분 (baseUrl는 꼭 / 로 끝나야 함, 아니면 예외 발생)
- Converter는 여러개 등록 가능, 등록 순서대로 변환 가능여부 판단, 변환 불가능하면다음 컨버터 확인
GsonConverter를 마지막에 넣는걸 추천 (Gson은 변환이 불가능해도 가능하다고 반응함)
Interface 객체 구현
- retrofit을 통한 객체 구현, 추상 메소드 중 사용할 메소드 Call 객체에 등록
동기 / 비동기 통신작업 실행
- 비동기 enqueue 작업으로 실행, 통신종료 후 이벤트 처리를 위해 Callback 등록
- onResponse 성공 / onFailure 실패 구분하여 메인스레드에서 처리할 작업 등록
(onResponse가 무조건 성공 X, 실패코드(3xx & 4xx 등)에도 호출 - isSuccesful() 확인이 필요package com.test.retrofitstudy import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import android.view.LayoutInflater import android.view.ViewGroup import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import com.bumptech.glide.Glide import com.test.retrofitstudy.databinding.ActivityMainBinding import com.test.retrofitstudy.databinding.RvItemBinding import retrofit2.Call import retrofit2.Callback import retrofit2.Response import retrofit2.Retrofit import retrofit2.converter.gson.GsonConverterFactory import retrofit2.http.GET interface GithubService { @GET("users/Kotlin/repos") fun users(): Call<Repository> } class MainActivity : AppCompatActivity() { lateinit var activityMainBinding: ActivityMainBinding override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) activityMainBinding = ActivityMainBinding.inflate(layoutInflater) setContentView(activityMainBinding.root) val retrofit = Retrofit.Builder() .baseUrl("https://api.github.com") // baseUrl 등록( 반드시 '/'로 마무리 .addConverterFactory(GsonConverterFactory.create()) .build() val adapter = CustomAdapter() activityMainBinding.run{ recyclerView.adapter = adapter recyclerView.layoutManager = LinearLayoutManager(this@MainActivity) } activityMainBinding.buttonRequest.setOnClickListener{ val githubService = retrofit.create(GithubService::class.java) githubService.users().enqueue(object: Callback<Repository> { // enqueue 를 사용하여 비동기 통신 실행 + 통신 완료 후 이벤트 처리 위한 Callback 리스너 등록 override fun onResponse(call: Call<Repository>, response: Response<Repository>) { if(response.isSuccessful){ // 정상적으로 통신이 된 경우 여기 부분은 메인 스레드에서 작업하는 부분이다. activityMainBinding.textView.text = "통신 성공" adapter.userList = response.body() as Repository adapter.notifyDataSetChanged() } else { // 통신이 실패한 경우 // onRespons가 무조건 성공 응답이 아니기에 확인이 필요하다. activityMainBinding.textView.text = "통신 실패" adapter.userList?.clear() adapter.notifyDataSetChanged() } } override fun onFailure(call: Call<Repository>, t: Throwable) { // 인터넷 끊김, 예외 발생 등 시스템적인 이유 activityMainBinding.textView.text = "통신 오류" } }) } } inner class CustomAdapter: RecyclerView.Adapter<CustomAdapter.Holder>() { var userList: Repository? = null inner class Holder(val binding: RvItemBinding) : RecyclerView.ViewHolder(binding.root) { fun setUser(user: RepositoryItem?){ user?.let{ binding.textName.text = user.name binding.textId.text = user.git_url Glide.with(binding.imageAvater).load(user.owner.avatar_url).into(binding.imageAvater) } } } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): Holder { val binding = RvItemBinding.inflate(LayoutInflater.from(parent.context), parent, false) return Holder(binding) } override fun getItemCount(): Int { return userList?.size?: 0 } override fun onBindViewHolder(holder: Holder, position: Int) { val user = userList?.get(position) return holder.setUser(user) } } }
'Android Studio' 카테고리의 다른 글
RecyclerView를 AsyncListDiffer 을 이용하여 효율 높이기 (0) 2024.06.26 AVD Error while waiting for device 해결법 (1) 2023.12.18 FireBase RealTime Database셋팅 및 기초 사용법 (0) 2023.08.03 안드로이드 스튜디오 WorkManager (0) 2023.07.26 안드로이드 스튜디오 JSON 사용하기 (0) 2023.07.20