현치비

안드로이드 아키텍쳐 컴포넌트(Android Architecture Components) - 2부 본문

Android/Android Library

안드로이드 아키텍쳐 컴포넌트(Android Architecture Components) - 2부

현CHIBI 2017. 8. 4. 15:27

이번 시간은 ViewModel을 알아본다.


먼저 정의를 알아보자.


ViewModel


Activity는 가로 회전을 하게되면, 새로운 Activity의 인스턴스가 생성된다.


즉, 기존 Activity는 onPause -> onStop -> onDestory타서 죽고,


새로운 Activity가 새로 생성되어 onCreate -> onStart -> onResume를 탄다.


위가 왜 문제가 된다는 것일까?




위 첫 번째 Activity(보라+파란 색 화살표)에서 fetchUser() 메서드로 유저 정보를 가져온다.


가로 모드로 전환.


새로운 Activity가 다시 fetchUser() 메서드로 유저 정보를 가져온다.


중복 데이터 통신 == 데이터 낭비 + 배터리 낭비


ViewModel을 쓰면 다음과 같이 해결할 수 있다.



Activity가 가로모드로 전환이 되어도 fetchUser()는 계속 실행이 된다.


핵심은 가로<->세로 모드 전환시에도 문제없이 동작할 수 있도록 하는 것이 ViewModel 이다.


사용법을 알아보자.


public class MyActivity extends AppCompatActivity {
   
public void onCreate(Bundle savedInstanceState) {
       
MyViewModel model = ViewModelProviders.of(this).get(MyViewModel.class);
        model
.getUsers().observe(this, users -> {
           
// update UI
       
});
   
}
}

new MyViewModel()을 하는 것이 아닌, ViewModelProviders.of(this).get() 메서드를 통해서 가져온다.


생각보다 쉽다.


LiveData를 ViewModel에서 들고 있는 경우가 많다.


3부에서 LiveData 설명과 함께 알아보자.


심화학습


필자는 ViewModel를 사용해보았는데


유의해야할 사항이 있었다.


1. SavedInstanceState와는 뭐가 다를까?


- savedInstanceState를 사용하려면 Serializable을 구현해야 하고, API 응답을 받은 데이터를 전부 Bundle에 넣는 것은 메모리를

많이 잡아먹는다.

- 그렇다고 savedInstanceState를 안쓰면 안되는 점이 있다.

  - 앱의 프로세스가 죽는 경우, ViewModel은 다 없어진다. (글꼴 변경, 권한 변경, 앱을 켰다가 우선순위에서 많이 뒤로 밀린 경우등)

  - savedInstanceState는 그 데이터를 저장한다.

즉 필자는 네트워크 통신에 요청할 파라미터정도만 savedInstanceState에 저장하고, 결과 요청이나 결과 값은 ViewModel에 저장한다.

앱의 프로세스가 죽을 경우 savedInstanceState에 저장된 데이터로 데이터를 재요청하면 된다.


결론은, 가로<->세로 모드 전환은 ViewModel, 앱의 프로세스가 죽을 경우를 대비하여 savedInstanceState를 사용해라



2. ViewModel이 사라질 경우가 있다.


Fragment1에는 FragmentViewModel1

Fragment2에는 FragmentViewModel2


한 Container에 Fragment1를 add한다.

그 Container에 Fragment2를 replace + addToBackStack을 한다.

그리고 가로 회전을 하고, 뒤로가기를 하면 Fragment1에 FragmentViewModel1은 사라져있다.


Replace된 Fragment1(활성화되지 않은 Fragment)가 가로모드로 전환이 되어버리면, 

Fragment가 사라지게 되고, FragmentViewModel1도 사라지게 된다.


이 문제를 해결하기 위해서, ViewModel의 lifecycle을 Activity의 Lifecycle로 등록을 했다.

-> 하지만 Activity의 Lifecycle이 늘어나는 문제가 발생할 수도 있다.


Fragment1과 Fragment2를 특정 ParentFragment의 ChildFragment로 두어서 

ViewModel이 ParentFragment의 Lifecycle을 참조했다.


결론은, Fragment의 ViewModel이 사라지는 경우가 있으니, ViewModel의 Lifecycle은 

그 Fragment의 Activity나 ParentFragment의 Lifecycle을 사용해라.


2부 마침.


이해가 안가시는 부분에 댓글 남겨주시면 친절히 설명드리겠습니다 :)


Comments