사전작업
레트로핏 공식 사이트
https://square.github.io/retrofit/
Retrofit
A type-safe HTTP client for Android and Java
square.github.io
레트로핏을 위한 준비사항
데이터를 가져올 곳(웹 사이트 또는 API 서버) 결정
✔ 예제에서는 Github API 중에서 사용자 정보를 검색하고 사용자 정보의 저장소를 보여주는 API를 다룰 예정이다.
https://docs.github.com/en/rest
GitHub REST API - GitHub Docs
docs.github.com
어떤(표준 프로토콜) 데이터를 사용할 것인지 데이터의 형식을 결정
✔ HTML은 구조가 복잡해서 짧은 시간에 분석하고 처리하기에는 불가능한 수준의 프로토콜이다.
✔ JSON은 데이터 교환에 사용하느 표준 데이터 형식으로 사람과 컴퓨터가 이해하기 쉬우면서 데이터 용량이 적다는 장점이 있다.
✔ JSON은 HTTP와 같은 데이터 프로토콜에서 바디 영역에 정의된 데이터 통신을 위한 개방형 규격이다.
JSON의 구조
JSON 오브젝트(객체)
JSON 데이터
JSON 배열
깃허브 사용자 정보를 가져오는 앱 개발하기
설계하기
✔ 깃허브에서 가져온 목록 데이터에는 이미지 정보인 아바타 주소가 포함되어 있다.
✔ 이미지를 화면에 보여주기 위해서는 이미지 로딩 라이브러리를 사용할 수 있는데, 예제에서는 Glide 라이브러리를 사용할 것이다.
✔ 이미지 로딩 라이브러리는 이미지가 있는 URL 주소만 알려주면 해당 이미지가 있는 서버에 접속하여 이미지를 다운로드해서 이미지뷰에 보내는 편리한 도구이다.
✔ Glide 홈페이지
https://github.com/bumptech/glide
GitHub - bumptech/glide: An image loading and caching library for Android focused on smooth scrolling
An image loading and caching library for Android focused on smooth scrolling - GitHub - bumptech/glide: An image loading and caching library for Android focused on smooth scrolling
github.com
Retrofit dependencies 추가
build.gradle
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
◽ converter-gson은 레트로핏에서 JSON 데이터를 사용하기 위해서 사용하는 부가적인 라이브러리이다.
Glide dependencies 추가
build.gradle
plugins {
id 'kotlin-kapt'
}
implementation 'com.github.bumptech.glide:glide:4.11.0'
// annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0' // < 동작안함
kapt 'com.github.bumptech.glide:compiler:4.11.0'
◽ 의존성과 함께 kapt 설정을 추가한다.
◽ 공식 홈페이지에는 annotationProcessor를 사용하라고 되어 있지만, 스튜디오 버전에 따라 정상 동작하지 않을 수 있다.
✔ 이렇게만 하면 동작하지 않으며, 가상의 클래스를 하나 만들고 @GlideModule 에너테이션을 사용하는 코드를 추가해야 한다.
MyGlideApp.kt
@GlideModule
class MyGlideApp: AppGlideModule()
권한 설정하고 데이터 클래스 정의하기
AndroidManifest.xml
<uses-permission android:name="android.permission.INTERNET"/>
Plugin : JSON To Kotlin
✔ 안드로이드 스튜디오에는 JSON 형식으로 된 텍스트 데이터를 코틀린 클래스로 간단하게 변환하게 해주는 플러그인을 지원한다.
✔ [ File ] - [ Settings ] - [ Plugins ] - [ JSON To Kotlin Class 검색 ] - [ Search in marketplace 클릭 ] - [ 다운로드 ]
✔ 웹 브라우저 https://api.github.com/users/Kotlin/repos 에서 JSON 데이터를 모두 복사한다.
✔ 이제 이것을 안드로이드 스튜디오에서 데이터 클래스로 변환할 것이다.
✔ [ 기본 패키지 우클릭 ] - [ New ] - [ Kotlin data class File from JSON ] - [ 붙여넣기 ] - [ 클래스 이름 지정 ]
화면 만들기
activity_main.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
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">
<Button
android:id="@+id/buttonRequest"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginLeft="24dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="24dp"
android:layout_marginRight="24dp"
android:text="GITHUB 사용자 가져오기"
android:textSize="24sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginStart="24dp"
android:layout_marginLeft="24dp"
android:layout_marginTop="4dp"
android:layout_marginEnd="24dp"
android:layout_marginRight="24dp"
android:layout_marginBottom="24dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/buttonRequest" />
</androidx.constraintlayout.widget.ConstraintLayout>
|
cs |
item_recycler.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
|
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
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="100dp">
<ImageView
android:id="@+id/imageAvatar"
android:layout_width="108dp"
android:layout_height="0dp"
android:layout_marginStart="16dp"
android:layout_marginLeft="16dp"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:srcCompat="@tools:sample/avatars" />
<TextView
android:id="@+id/textName"
android:layout_width="244dp"
android:layout_height="0dp"
android:layout_marginStart="8dp"
android:layout_marginLeft="8dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:text="이름"
android:textSize="20sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/imageAvatar"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/textId"
android:layout_width="244dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginLeft="8dp"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:layout_marginBottom="16dp"
android:text="아이디"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/imageAvatar"
app:layout_constraintTop_toBottomOf="@+id/textName"
app:layout_constraintVertical_bias="0.515" />
</androidx.constraintlayout.widget.ConstraintLayout>
|
cs |
리사이클러뷰 어댑터 만들기
CustomAdapter.kt
class CustomAdapter:RecyclerView.Adapter<Holder>() {
var userList : Repository? = null // 어댑터에서 사용할 데이터 컬렉션을 변수로 만들기기
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): Holder {
val binding = ItemRecyclerBinding.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)
holder.setUser(user)
}
}
class Holder(val binding: ItemRecyclerBinding): RecyclerView.ViewHolder(binding.root){
fun setUser(user:RepositoryItem?) {
user?.let {
binding.textName.text = it.name // 사용자 이름
binding.textId.text = it.node_id // 사용자 ID
Glide.with(binding.imageAvatar).load(it.owner.avatar_url).into(binding.imageAvatar)
// 아바타 주소
}
}
}
레트로핏 사용하기
MainActivity.kt
class MainActivity: AppCompatActivity() {
val binding by lazy { ActivityMainBinding.inflate(layoutInflater) }
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(binding.root)
/* 리사이클러뷰와 어댑터 연결 */
val adapter = CustomAdapter()
binding.recyclerView.adapter = adapter
binding.recyclerView.layoutManager = LinearLayoutManager(this)
val retrofit = Retrofit.Builder()
.baseUrl("https://api.github.com/")
.addConverterFactory(GsonConverterFactory.create())
.build()
binding.buttonRequest.setOnClickListener {
// 앞에서 정의한 인터페이스를 파라미터로 넘겨주면 실행 가능한 서비스 객체를 생성해서 반환
val githubService = retrofit.create(GithubService::class.java)
// 비동기 통신으로 데이터를 가져오는 enqueue()를 시작하면 통신이 시작된다.
githubService.users().enqueue(object: Callback<Repository> {
override fun onFailure(call: Call<Repository>, t: Throwable) {
/* */
}
override fun onResponse( // 통신 성공
call: Call<Repository>,
response: Response<Repository>
) {
adapter.userList = response.body() as Repository // 서버에서 받은 데이터 꺼내기
adapter.notifyDataSetChanged()
}
})
}
}
}
/*
* 레트로핏을 사용하기 위해서는 인터페이스가 정의되어 있어야 한다.
* 레트로핏 인터페이스는 호출 방식, 주소, 데이터 등을 지정한다.
* Retrofit 라이브러리는 인터페이스를 해석해서 HTTP 통신을 처리한다.
* import는 retrofit2 패키지를 선택
*/
interface GithubService {
@GET("users/Kotlin/repos") // 요청 주소 설정(도메인은 제외)
fun users(): Call<Repository> // 반환값은 Call<List<데이터 클래스>>
}
'Android > Concept' 카테고리의 다른 글
[Android] [Kotlin] Context (0) | 2021.11.05 |
---|---|
[Android] [Kotlin] 파일 입출력 (0) | 2021.09.26 |
[Android] [Kotlin] 네트워크 (0) | 2021.09.25 |
[Android] [Kotlin] 콘텐트 리졸버 (0) | 2021.09.23 |
[Android] [Kotlin] 서비스 (0) | 2021.09.22 |