Offline

2019 Google IO – Architecture Components 정리

May 10, 2019

2019 Google IO – Architecture Components 정리

2019년 Google IO 중 Architecture Components 세션에서 소개한 내용을 몇 가지 정리한다.

세션 내용은 아래에서 감상할 수 있다.

 

Jetpack Architecture Components

Architecture Components는 이미 너무 많이 사용하고 있다고 하는데, 아래와 같이 수치를 공개해주었다.

생각보다 많은 개발자가 Architecture Components를 사용하는데 서베이 기준 70%를 사용하고 있다고 한다.

image_01
image_01

Architecture Components는 아래와 같은 과정을 거쳐 Alpha > Beta > Stable의 과정을 거쳤다고 한다.

이런 내용은 처음 공개하는 내용인데 많은 커뮤니티들을 통해 피드백을 받고 업데이트했다고 한다.

image_02
image_02

Kotlin First를 한 번 더 언급하였고, 이제는 KTX로만 코틀린 관련 라이브러리를 배포하지 않고, API 디자인도 코틀린을 사용한다고 한다.

결국 이 말은 Java만을 사용하는 안드로이드 개발에서도 기본 Kotlin을 추가해야 사용 가능해진다는 이야기다.

Kotlin은 이제 기본으로 적용해야, 앞으로 나올 Jetpack Architecture 라이브러리 활용이 가능해진다는 말이다.

image_03
image_03

 

Data Binding

Data Binding은 XML에서 Code를 바로 바인딩 할 수 있는 라이브러리이고, 아래와 같이 사용할 수 있다.

<layout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto">
    <data>
        <variable
            name="viewModel"
            type="com.myapp.data.ViewModel" />
    </data>
    <ConstraintLayout...>
      <TextView
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:text="@{viewModel.firstName}"/>
    <ConstraintLayout>
</layout>

Android Studio 3.5 베타 기준으로 아래와 같은 성능 향상이 일어났고, Incremental annotation processing을 위한 옵션이 추가되었다.

image_04
image_04

 

Android Studio 3.5부터 달라지는 부분

Live Class Generation이 가능해졌다. 항상 리빌드를 하던 이전과는 달리 3.5부터는 실시간으로 처리가 가능하다.

아래 그림은 영상에서 확인하면 좋겠지만 xml의 TextView에 id를 추가하고, 이를 리빌드 없이 즉시 code에서 확인이 가능하다.

rebuild로 인해 생기는 대기시간을 최소화할 수 있게 되었다.

image_05
image_05

Refactoring도 지원하는데, Code에서 변수 이름을 Rename을 통해서 변경하면 이 역시 즉시 반영한다.

드디어… 해줬다.

image_06
image_06

또 하나 Data Binding 컴파일 오류를 확인할 수 있게 되었다.

image_07
image_07

이제서야 Data Binding을 진짜 잘 사용할 수 있게 되었다. 3.4까지 제공하던 Data Binding은 그나마 쓸 수 있을 정도였다면 3.5 버전부터는 잘 사용할 수 있게 되었다. 이제 좀 잘 사용해보자.

 

Data Binding이 아닌 새로운 View Binding

이번 발표에서는 Data Binding이 아닌 View Binding도 소개했다.

아름다운 코드 적용, 컴파일 타임 안전성을 확보하고, 빌드 속도까지 좋다고 한다. 하지만 당장 사용할 순 없다. Android Studio 3.6 버전부터 제공할 예정이다.

image_08
image_08

안전한 이유는 object로 이들을 관리함으로써 기존에 type이 맞지 않던걸 해결했다고 한다.

image_09
image_09

Java에서도 지원하며, Gradle 플러그인을 통해 Binding 클래스가 만들어지고, 100% 컴파일 타임에 안전하며, Studio와 통합되어 있다. 그리고 데이터 바인딩과도 호환 가능하다.

image_10
image_10

 

ViewModel

ViewModel과 관련한 새로운 소식은 SavedState를 추가 지원한다는 것이다.

ViewModel SavedState는 SavedStateHandler를 통해 제공하는데, 기존 ViewModel에 아래와 같이 추가하여 사용할 수 있다.

image_11
image_11

초기화 코드는 문서에 나와있는데, 아래와 같다.

val vm = ViewModelProvider(this, SavedStateVMFactory(this))
        .get(SavedStateViewModel::class.java)

SavedStateHandler를 사용해서 아래와 같이 read/write를 할 수 있는데,

image_12
image_12

handler의 LiveData를 활용해서도 이를 사용하는 게 가능하다.

image_13
image_13

하지만 SavedStateHandler를 사용하더라도 큰 기대는 하지 말길…

Parcelable data를 적용해야 하고, data size는 기존과 동일하게 적용되어야 한다.

 

ViewModel 초기화 코드가 줄었다.

ViewModel 초기화 코드가 줄어들었다. koin을 사용하는 사람은 쉽게 이해가 가능하고, 필자도 이런 비슷한 걸 만들어 쓰긴 했다.

아래와 같이 ViewModel을 초기화했었으나,

ViewModelProviders.of(this).get(MyViewModel::class.java)

이제는 by를 사용하여 초기화 가능해졌다.

val myViewModel: MyViewModel by viewModels()

 

WorkManager

WorkManager의 활용 방법이 변경되었다.

WorkManager Sample을 통해 바로 확인 가능하다.

Application을 상속받아 구현하는 구현체에서 Configuration.Provider을 상속받아 아래와 같이 초기화한다. 이때 build() 사이에는 필요한 옵션들을 정의할 수 있다.

class App : Application(), Configuration.Provider {
    override fun getWorkManagerConfiguration() =
            Configuration.Builder()
                    .setMinimumLoggingLevel(Log.VERBOSE)
                    .build()
}

그리고 WorkManager 활용 시 context를 넘겨서 처리할 수 있다.

WorkManager.getInstance(context)

이러한 샘플은 WorkManager Sample에서 확인할 수 있다.

 

Worker unit test

Worker에 대한 unit test가 alpha에서 가능해진다.

크게 TestWorkerBuilder와 TestListenableWorkerBuilder이다.

image_14
image_14

기본적인 work 테스트는 아래와 같은데 doWork()의 결과를 확인할 수 있다.

image_15
image_15

이번엔 listenable worker에 대한 테스트도 아래와 같다.

image_16
image_16

추가로 Sample에 있는 ImageOperationsTest.kt에 observe 형태의 테스트를 확인할 수 있다.

마지막으로 Foreground service를 지원하는데 notification 아이콘을 노출하는 조건이다.

 

Room

Room에서 달라진 정보를 소개한다.

Room 2.0에서는 아래와 같이 query를 작성하였으나,

image_17
image_17

Room 2.1부터는 별도의 쿼리 대신 data class를 직접 사용할 수 있다고 한다.

@Dao
interface SongDao {
  @Query("""
    SELECT *
    FROM Song
    WHERE Song MATCH :query
  """)
  fun searchSongs(query: String): List<Song>
}

 

Database views

Room 2.1부터 Database views를 제공한다.

@DatabaseView("SELECT user.id, user.name, user.departmentId," +
        "department.name AS departmentName FROM user " +
        "INNER JOIN department ON user.departmentId = department.id")
data class UserDetail(
    val id: Long,
    val name: String?,
    val departmentId: Long,
    val departmentName: String?
)

이를 사용할 때는 아래와 같다.

@Database(entities = arrayOf(User::class),
          views = arrayOf(UserDetail::class), version = 1)
abstract class AppDatabase : RoomDatabase() {
    abstract fun userDao(): UserDao
}

 

마무리

2일차에 나온 Google IO 중 Architecture Components에서 Data Binding, ViewModel, WorkManager, Room에 대해서 정리하였다. 나머지는 영상을 통해 확인 가능하다.