앱 아키텍처를 위한 Jetpack 컴포넌트
Jetpack 컴포넌트
Jetpack 컴포넌트는 생산성을 높여 개발할 수 있게 돕는 라이브러리, 도구, 가이드의 모음이다. Jetpack에서 애플리케이션을 설계하는 권장 사항을 따르고, 보일러 플레이트(?)를 줄이고, 복잡한 작업을 간소화함으로써 중요한 코드에만 집중할수 있다.
보일러플레이트란?
컴퓨터 프로그래밍에서 보일러플레이트 또는 보일러플레이트 코드라고 부르는 것은 최소한의 변경으로 여러곳에서 재사용되며, 반복적으로 비슷한 형태를 띄는 코드를 말한다.
Jetpack은 안드로이드 프레임워크가 아닌 androidx.* 패키지 라이브러리고 제공된다. 이는 하위 버전과 호환하기 위함이며, Android 플랫폼보다 더 자주 업데이트 된다. 그러므로 항상 최신 Jetpack 컴포넌트를 유지하는 것을 추천한다.
Jetpack은 크게 기초(Foundation), 아키텍처(Architecture), 동작(Behavior), 사용자 인터페이스(User Interaface) 4개의 카테고리로 분류된다.
Jetpack 아키텍처에는 다음과 같은 라이브러리들이 속한다.
- Data Binding
- Lifecycles
- LiveData
- Navigation
- Paging
- ViewModel
- WorkManager
1. 데이터 바인딩
데이터 바인딩은 명령형 방식(X)이 아닌 선언적 형식(O)으로 레이아웃의 UI구성 요소를 앱의 데이터와 결합할 수 있는 라이브러리이다.
선언형 프로그래밍이란 문제에 대한 답을 정의하기보다는 문제를 설명하는 것이다.
명령형 프로그래밍은 "어떤 방법"으로 할지에 중줌을 두는 반면에, 선언형 프로그래밍 언어는 "무엇"을 할지에 중점을 둔다.
a) 데이터 바인딩 설정하기
Android 4.0(API 14Level) 이상 안드로이드 기기에서 지원.
1) build.gradle에 설정
2) binding class 생성하기
1) build.gradle에 설정
android {
...
/* DataBinding 사용하기 위해 추가*/
dataBinding {
enabled = true
}
...
}
데이터 바인등 설정이 끝나면 아래 기능들이 활성화 됨
- 구문 강조
- 데이터 바인딩 표현식 오류 검출
- XML 코드 자동완성
- 빠른 코드 참조
2) binding class 생성하기
데이터 바인딩 라이브러리는 레이아웃의 변수와 뷰를 참조할 수 있는 바인딩 클래스를 생성한다. 모든 생성되는 바인딩 클래스는 ViewDataBinding을 상속한다. xml 레이아웃 파일에서 가장 상위 레이아웃을 <layout>테그로 감싸면 바인딩 클래스가 자동으로 생성된다.
1.activity_main.xml 2. User.java 3. MainActivity.java
1. activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<layout>
<data>
<variable
name="user"
type="com.practice.User"/>
</data>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{user.firstName}"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{user.lastName}"/>
</LinearLayout>
</layout>
2. User.java
public class User {
private final String firstName;
private final String lastName;
public User(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
}
3. MainActivity.java
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 1.inflate 사용
//ActivityMainBinding binding = ActivityMainBinding.inflate(getLayoutInflater());
// 2. DataBindingUtil
ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
setContentView(binding.getRoot());
}
}
바인딩 표현식 알아보기
바인딩 표현식에 꽤 많은 문법이 존재한다. 다음 연산자와 키워드들을 xml 레이아웃에서 사용가능
- 산술 연산자 : + - / * %
- 문자열 연결: +
- 논리 연산자: && ||
- 비트 연산자: & | ^
- 단항 연산자: + - ! ~
- 비트 이동 연산자: >> >>> <<
- 비트 연산자: == > < >= <=
Null Pointer Exception
- 자동으로 생성된 바인딩 클래스는 자동으로 null을 검사하고 NPE를 회피한다. 예를 들어 @{user.name}이라는 표현식이 있고 user가 null 이라면 user.name은 기본적으로 null 배치된다.
Collection내용들도 사용가능
배열, 리스트, 맵 등과 같은 일반적인 Collections 클래스들은 다음과 같이 [ ] 연산자를 사용할 수 있다.
<data>
<import type="java.util.Map"/>
<variable name="user" type="com.practice.User"/>
<variable name="map" type="Map< String, String>"/>
<variable name="key" type="String"/>
</data>
...
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{map[key]}"/>
...
- <import> : <data> 태그 내에 <import> 태그를 사용하여, 참조하고 싶은 클래스를 레이아웃과 파일에 간단히 불러올 수 있다.
- <include> : 레이아웃 파일 내에서 다른 레이아웃을 포함하는 경우 <include> 태그를 사용할 수 있다. 데이터도 넘길수 있음.
이벤트 처리하기
데이터 바인딩은 onClick() 메서드 등과 이벤트를 뷰로부터 가져와서 처리할 수 있는 기능을 제공한다.
이벤트를 다루는 방법에는 메서드 참조와 리스터 바인딩등 두가지 방법이 있음.
메소드 참조
<Button android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="aaaaa"
android:onClick="onClickFriend"/>
리스너 바인딩
<Button android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="bbbbb"
android:onClick="@{() -> main.onClickFriend()}"/>
Observable 데이터 객체로 작업하기
Observable 데이터 객체란 데이터의 변경 사항을 감지하고 알려 주는 객체이다. 데이터 바인딩 라이브러리는 Observable 데이터 타입을 제공하고 지원한다.
- Observable 컬랙션 사용 (ex : ObservableArrayMap<String, object> user = new ObservableArrayMap<>(); )
- Observable 객체 사용 (BaseObservable을 상속해서 사용)
- 즉각적인 바인딩
ViewStub을 사용하면 불필요한 레이아웃의 전개를 막을 수 있기 때문에, 복잡한 레이아웃을 포함하는 RecyclerView 등에서 필수적으로 사용된다. (나중에 좀더 깊게 공부하기)