티스토리 뷰

이 글은 안드로이드 개발자 블로그 (Android Developers Blog) 에서 게제한 글을 번역한 것입니다.

2017년 구글 I/O에서 발표한 라이프사이클 관리를 위한 안드로이드 아키텍처 컴포넌트를 포함한 새로운 피처를 소개하고 있습니다.

안드로이드와 아키텍처

안드로이드 OS는 넓은 범위의 기기들이 잘 동작하도록 앱을 만들 수 있는 강력한 기반을 제공한다. 그리고 우리는 복잡한 라이프사이클 그리고 추천 아키텍처의 부족 등의 개발자 피드백을 들었다.

우리는 더 쉽고 즐겁게 탄탄한 앱을 만들면서 개발자들이 혁신적인 분야에 집중할 수 있도록 할 필요가 있다. 요즘 우리는 아키텍처 컴포넌트의 프리뷰와 함께 안드로이드 앱 아키텍처의 가이드를 발표하고 있다. '바퀴를 다시 만들기'보단 인기있는 안드로이드 라이브러리로 작업이 되는 것을 인지하고 있기도 하다.

처방전이 아닌 의견

안드로이드 앱을 제작할 수 있는 방법은 무궁무진하기 때문에 아키텍처링을 할 때 도움을 줄 수 있는 가이드라인을 제공하고 있다. 안드로이드 프레임워크는 잘 정의된 API이지만 여러분의 애플리케이션에서는 빌딩 블록이기보단 시작점일 뿐이다. 프레임워크 컴포넌트는 데이터 모델을 UI 컴포넌트로부터 분리시키는 것이나 데이터를 생애주기와 독립적으로 데이터를 지속화하는 깔끔한 방법을 강요하진 않는다.

빌딩 블록

아키텍처 컴포넌트는 정상적인 앱 아키텍처를 구현하도록 돕는다. 동시에 개발자의 고통의 포인트를 다뤄준다.

  • 자동으로 액티비티, 프레그먼트 라이프사이클을 다뤄 메모리와 리소스 릭을 피하기

  • 자바 데이터 객체를 SQLite 데이터베이스에 보존하기

라이프사이클 컴포넌트

새로운 lifecycle-aware 컴포넌트는 앱의 코어 컴포넌트를 묶을 수 있는 구성품을 제공한다. 전형적인 안드로이드 관찰 모델은 onStart()와 onStop()이다. 단순해보이지만 심각한 비동기 호출로 인해 에지 포인트를 놓치기 쉽다. 라이프사이클 컴포넌트는 이것을 돕는다.

핵심 클래스는 Lifecycle이다. 이것은 현재의 라이프사이클 상태와 이벤트를 사용한다.

LifecycleOwner는 getLifecycle() 메서드로 라이프사이클 객체를 리턴하는 인터페이스이다. LifecycleObserver가 컴포넌트의 라이프사이클 이벤트를 모니터링한다. 모두 합치면 라이프사이클을 모니터링하면서 현재 상태를 쿼리할 수 있는 컴포넌트를 생성할 수 있다.

LiveData

"관찰가능한 라이프사이클 어웨어 데이터 홀더 클래스"

변경될 때 알려주는 SharedPreference같은 느낌? 메모리 릭이나 액티비티가 멈출때 업데이트를 피하는 충돌을 줄일 수 있다.

라이플사이클 오너 (프레그먼트나 액티비티)는 LiveData 를 관찰할 수 있다.

ViewModel

UI 컨트롤러 로직으로부터 분리된 뷰 데이터 오너십을 보존하는 액티비티 또는 프레그먼트를 위한 UI 데이터를 가지는 헬퍼 클래스이다. 액티비티나 프레그먼트가 살아있는 동안 데이터를 보존하는데 configuration 변경으로 인해 destroy - recreated 되는 영역도 포함한다. LiveData가 알림부분을 다룬다면 ViewModel은 데이터가 적절하게 보존되도록 하는 역할이다.

Data Persistence

Room 라이브러리로 데이터 보존을 단순화할 수 있다. Room은 객체 매핑 추상화 레이어를 제공하는데 SQLite의 전체 능력을 활용하면서 유동적인 데이터베이스 접근할 수 있도록 한다.

코어 프레임워크는 raw SQL과 작업할 수 있는 빌트인 지원을 제공한다. API는 파워풀하지만 로우레벨이여서 사용하는데 시간과 노력이 꽤 필요하다.

  • raw SQL 쿼리의 컴파일 타임 확인이 없다.

  • 스키마가 변경되면 영향을 받는 SQL 쿼리를 수동으로 변경해야 한다. 이 프로세스는 시간 낭비이며 에러가 발생할 수 있다.

  • SQL 쿼리와 자바 데이터 객체 사이 많은 보일러 플레이트 코드가 필요하다.

Room은 이런 문제를 고려하고 추상 레이어를 제공한다.

Database, Entity, and DAO

Room에는 세가지 주요 컴포넌트가 있다.

  • Entity는 단일 데이터베이스 행이고 annotated Java data object로 구성된다. 각 Entity는 테이블을 소유한다.

  • DAO (Data Access Object) 는 데이터베이스에 접근하는 메서드를 정의한다. SQL을 각 메서드에 바인드하는 annotation을 사용한다.

  • Database는 엔티티 리스트와 데이터베이스 버전을 정의하기위한 annotation을 사용하는 홀더 클래스이다. 이 클래스는 DAO의 리스트를 정의한다. 역시 데이터베이스 연결에서의 주요 접근 포인트이다.

Room을 사용하기 위해선, 엔티티로서 자바 데이터 객체를 어노테이션화하고 이 엔티티를 가지는 데이터베이스를 생성하고 데이터베이스에 접근하고 수정하는 DAO 클래스를 SQL과함께 정의한다.

@Entity
public class User {
    @PrimaryKey
    private int uid;
    private String name;
    // Getters and Setters - required for Room
    public int getUid() { return uid; }
    public String getName() { return name; }
    public void setUid(int uid) { this.uid = uid; }
    public void setName(String name) { this.name = name; }
}

@Dao
public interface UserDao {
    @Query("SELECT * FROM user")
    List getAll();
    @Insert
    void insertAll(User... users);
}

@Database(entities = {User.class}, version = 1)
public abstract class AppDatabase extends RoomDatabase {
    public abstract UserDao userDao();
}

앱 아키텍처를 위한 가이드

아키텍처 컴포넌트는 standalone으로 설계되었지만 효과적인 앱 아키텍처와 합쳐질 때 가장 효과적이다. 어떻게 탄탄하고 모듈화된 그리고 테스트가능한 앱을 만드는지 보여주고 있다. 이 가이드는 세가지 목표가 있다.

  • 안드로이드 앱 개발에 적용하는 원칙을 정의하는 것

  • 그 원칙들을 적용하는 앱 아키텍처를 보이는 것

  • 아키텍처 컴포넌트를 사용해 그 아키텍처를 어떻게 구현하는지 보이는 것

마지막으로 안드로이드 앱 아키텍처에 대해 더 배울 수 있는 링크

참고문헌

https://android-developers.googleblog.com/2017/05/android-and-architecture.html?utm_source=Android+Weekly&utm_campaign=293483b394-android-weekly-258&utm_medium=email&utm_term=0_4eb677ad19-293483b394-338129525

댓글