Jetpack
JetPack전체
JetPack 아키텍처
ViewModel
UI controller의 데이터를 캡슐화하여 구성이 변경되어도 데이터를 유지하게 하기 위해
ViewModel이 나타난 이유
- 데이터가 Activity에 종속적이여서 데이터 관리의 힘듦
ex) configuration change가 일어났을 때 데이터 사라짐 -> simple data의 onSaveInstanceState()를 써서 bundle에 저장한 후, onCreate()에서 불러다 쓴다.
한계) 적은 양의 데이터에만 적합(serialized 되는): 많은 양의 UserList나 BitmapList에 적합 X - 역할분리: Activity/Fragment는 UI데이터를 보여주고, 사용자애션에 반응하고, OS communication을 처리하기 위한 것인데, DB나 network 까지 하기 힘들어서
ViewModel LifeCycle
LiveData
LifeCycle을 알고 있는 DataType
LiveData 값 변경 적용여부
Observer패턴
어떤 객체에 이벤트가 발생했을 때, 이 객체와 관련된 객체들(옵저버들=구독자들)에게 통지하도록 하는 디자인 패턴
따라서, 데이터의 변경이 일어났을때 콜백으로 받아 처리할 수 있다.
https://woovictory.github.io/2019/04/30/What-is-LiveData/
https://medium.com/harrythegreat/jetpack-android-livedata-%EC%95%8C%EC%95%84%EB%B3%B4%EA%B8%B0-ed49a6f17de3
사용방법
1. LiveData생성 = 보통 ViewModel에서
LiveData<T> data = new MutableLiveData<>();
LiveData<T> data = new MediatorLiveData<>();
2. LiveData 구독 = observe(viewModelOwner, Observer); / 보통 UI(Activity/Fragment)에서
viewModel.data.observe(ViewModelOwner, T -> {
// UI갱신 등의 작업
});
3. 콜백실행 = setValue() / postValue()
data.setValue(data); //Main Thread에서 실행
data.postValue(data); //Background Thread에서 실행
4. 그 외 함수
- Transformations
- map(): LiveData의 변경을 다른 LiveData에게 알려주는 메소드
- switchMap(): 인자값(여기서는 id)에 따라 다른 LiveData 발행
LiveData<String> userInfo = Transformations.map(mUserViewModel.getUser(), user ->
user.getName() + user.getEmail());
LiveData<User> userLiveData = Transformations.switchMap(mUserViewModel.getUserId(), id ->
getUser(id));
- MediatorLiveData: 여러 데이터 소스를 한 곳에서 Observe할 때 사용
MediatorLiveData<User> userManageLiveData = new MediatorLiveData<>();
LiveData<User> userLiveData1 = new MutableLiveData<>();
LiveData<User> userLiveData2 = new MutableLiveData<>();
userManageLiveData.addSource(userLiveData1, user -> userManageLiveData.setValue(user));
userManageLiveData.addSource(userLiveData2, user -> userManageLiveData.setValue(user));
Room
ORM라이브러리 / DB의 객체를 java/kotlin 객체로 매핑 / SQLite의 추상레이어 위에 제공
ORM
(Object Relation Mapping) DB테이블과 매핑되는 객체를 만들고, 그 객체에서 DB를 관리
Room 아키텍처
사용방법
- Entity로 사용할 Data Class 만들기 = 테이블
- DAO만들기 = 쿼리
Annotation으로 관리 / LiveData, RxJava를 이용하면 Observable query 이용 가능 - Database만들기
Database 접근지점 제공, DAO 관리
Annotation에 사용할 Entity 목록을 작성해야 함
https://woovictory.github.io/2019/01/25/Android-Room-Basic/
https://medium.com/harrythegreat/android-room-database-%EC%8B%9C%EC%9E%91%ED%95%98%EA%B8%B0-f2019cdced0c
ViewModel+LiveData+Room+Retrofit Architecture
ViewModel+LiveData Architecture
DataBinding
xml-data 객체랑 이어줌
https://woovictory.github.io/2019/02/04/Android-What-is-DataBinding-1/
Paging
대용량 데이터 페이징 API(network/db)
https://gamjatwigim.tistory.com/101?category=716500
https://medium.com/@eyegochild/android-paging-library-in-jetpack-1-overview-e40e7ce85d96
https://proandroiddev.com/8-steps-to-implement-paging-library-in-android-d02500f7fffe
https://medium.com/@eyegochild/android-paging-library-in-jetpack-1-overview-e40e7ce85d96
용어
- DataSource: Network, Memory, DB로 부터 페이징 데이터를 질의하는 역할의 추상 클래스
- PageKeyDataSource: 데이터가 다음, 이전의 키를 포함하고 있을 때
- ItemKeyedDataSource: N번째 데이터로 N-1/N+1의 데이터를 가져올 때
- PositionalDataSource: 특정 위치의 데이터를 가져올 때(Room은 PositionalDataSource인 DataSource.Factory를 반환)
- PagedList
- LivePagedListBuilder: LiveData를 이용하여 데이터 관찰 -> LiveData<PagedList>객체로 받을 수 OK
(DataSouce.Factory 와 PagedList.Config 혹은 page size 와 같은 설정을 인자로 받아
를 생성)LiveData<PagedList<Value>>
- RxPagedListBuilder: RxJava2를 이용하여 데이터 관찰. 이를 이용하면
객체를 받을 수 OKFlowable<PagedList<T>> Observable<PagedList<T>>
- PagedListAdapter
- PagedList.BoundaryCallback: PagedList가 사용 가능한 데이터의 끝에 도달했을 때 콜백을 받는 추상 클래스. LivePagedListBuilder 에 넘겨서 사용함 (네트워크와 데이터베이스 같이 사용하는 경우 구현)
- PagedList.Config: PagedList가 DataSource에서 가져오는 데이터의 크기, 미리 불러오는 데이터 크기 등을 정의
- DataSource.Factory: DataSource를 감싸 LivePagedListBuilder 로 넘김. 내부적으로 DataSource의 인스턴스 생성을 제어하기 위함
- RxPagedListBuilder : LivepagedListBuilder와 유사하게, RxJava2 기반의 기능을 제공한다. 이 클래스는 아키텍쳐 라이브러리의 RxJava2 기반으로 제공됩니다. 이 클래스를 사용하여, PagedList를 구현할 때 Flowable과 Observable을 생성할 수 있음
구현방법
- 라이브러리 추가
- DataSource 선택/구현: 데이터를 어디서, 어떻게 가져올 지 정의하는 단계
- PagedList 생성: 데이터 갱신을 어떤 방식으로 관찰할 지 정의하는 단계
- PagedListAdapter 구현: 전달받은 PagedList 객체를 이용하여, 데이터의 변경이 있는지 여부를 확인하여 UI(RecyclerView)를 구성하는 단계
- 어댑터 연결 & 데이터바인딩: RecyclerView에 만들어진 어댑터를 연동하고, PagedListBuilder의 결과를 구독하여, 어댑터에 갱신된 데이터를 넣어준다.
Navigation
앱 내의 화면 전환, 흐름을 UI적으로 볼 수 있게 해줌
https://brunch.co.kr/@oemilk/210
용어
1. Destination - Navigation을 이용해 이동하는 앱의 특정 화면(ex. Activity, Fragment, Navigation Graph, ...)
2. Navigation Graph - destinations 과 이들을 연결하는 action들을 시각화해서 볼 수 있음
3. NavHostFragment
- Fragment 상속
- NavHost interface를 구현 = NavController를 반환하는 interface
app:defaultNavHost="true" -> 시스템의 back button 이벤트 intercepter가능
4. NavController
Navigation Graph에서 정의한 Destination action을 수행하기 위해 NavController 필요
NavHostFragment를 통해 얻음
Lifecycles
annontation으로 lifeCycle에 따라 정의 가능
https://codechacha.com/ko/android-jetpack-lifecycle/
WorkManager
사용자의 기기 API 수준 등에 따라 JobScheduler, AlarmManager 등의 라이브러리를 적절히 사용하여 Background 작업을 관리
충전중인 상태, 배터리 상태, 저장공간 상태 등...
'Platform > Android' 카테고리의 다른 글
[Error] lombok과 Room을 같이 쓸 때-Cannot fine getter for field (0) | 2020.04.14 |
---|---|
[Error] lombok 적용이 안될 때-Annotation processors must be explicitly declared now. (0) | 2020.04.13 |
ViewModel / LiveData / RecyclerView (0) | 2020.03.27 |
[AAC] ViewModel | LiveData (0) | 2020.03.18 |
[Class] (0) | 2020.03.17 |