- 클래스를 사용 ViewModel 하여 생명 주기를 고려한 방식으로 UI 관련 데이터를 저장하고 관리합니다. 이 ViewModel 클래스를 사용하면 화면 회전 및 키보드 가용성 변경과 같은 장치 구성 변경 후에도 데이터를 유지할 수 있습니다.
- 화면에 표시할 데이터와 해당 데이터를 처리할 코드
- 액티비티, 프래그먼트 및 뷰는 구성 변경 후에도 유지되지 않으므로 프래그먼트, 액티비티 또는 뷰에 대한 ViewModel 참조를 포함해서는 안 됩니다.
- 비교를위해 추가하기 전과 추가 한 후에 GameFragment 시작 앱에서 UI 데이터가 처리하는 방법은 다음과 같다.
- 추가하기 전 : 앱이 화면 회전 등의 설정 변경을 하면 게임 프래그먼트가 소멸되어 재생성됩니다. 데이터가 손실됩니다.
- 추가한 후 : 조각이 표시해야 하는 모든 데이터는 이제 앱 구성 변경을 ViewModel 거치면 살아남고 데이터가 유지됩니다.
- 시스템이 UI 컨트롤러를 파괴하거나 다시 저장한 일시적인 UI 관련 데이터가 손실됩니다. 예를 들어 앱의 활동 중 하나에 사용자 목록이 포함 될 수 있습니다. 구성 변경을 위해 활동이 다시 생성되면 새 활동은 사용자 목록을 다시 가져와야 합니다. 간단한 데이터의 경우 활동은 onSavedInstanceState()메서드를 사용하고 번들에서 데이터를 복원 할 수 있는 onCreate() 있지만 이 접근 방식은 직렬화한 다음 역질렬화할 수 있는 소량의 데이터에만 적합하며 사용자 목록 또는 비트맵.
- 또 다른 문제는 UI 컨트롤러가 반환하는데 시간이 걸릴 수 있는 비동기식 호출을 자주 수행햐야 한다는 것입니다. UI 컨트롤러는 이러한 호출을 관리하고 잠재적인 메모리 누수를 방지하기 위해 파괴된 후 시스템이 이를 정리하도록 해야 합니다. 이 관리에는 많은 유지 관리가 필요하며 구성 변경을 위해 개체를 다시 만드는 경우 개체가 이미 만든 호출을 다시 발행햐애 할 수 있으므로 리소스 낭비입니다.
- 액티비티 및 프래그먼트와 같은 UI 컨트롤러는 주로 UI 데이터를 표시하고, 사용자 작업에 반응하거나, 권한 요청과 같은 운영 체제 통신을 처리하기 위한 것입니다. 또한 UI 컨트롤러가 데이터베이스나 네트워크에서 데이터를 로드하도록 요구하면 클래스가 부풀려집니다. UI 컨트롤러에 과도한 책임을 할당하면 다른 클래스에 작업을 위함하는 대신 자체적으로 앱의 모든 작업을 처리하려고 하는 단일 클래스가 생성 될 수 있습니다. 이러한 방식으로 UI 컨트롤러에 과도한 책임을 할당하면 테스트가 훨씩 더 어려워집니다.
- UI 컨트롤러 로직에서 뷰 데이터 소유권을 분리하는 것이 더 쉽고 효율적입니다.
- 아키텍처 구성 요소는 ViewModel U에 대한 데이터 준비를 담당하는 UI 컨트롤러에 대한 도우미 클래스를 제공합니다. ViewModel 개체는 구성 변경 중에 자동으로 유지되므로 개체가 보유한 데이터를 다음 활동 또는 조각 인스턴스에서 즉시 사용할 수 있습니다. 예를 들어 앱에 사용자 목록을 표시해야 하는 ViewModel 경우 다음 샘플 코드와 같이 액티비티나 프래그먼트 대신에 사용자 목록을 획득하고 유지할 책임을 할당해야 합니다.
class MyViewModel : ViewModel() {
private val users: MutableLiveData<List<User>> by lazy {
loadUsers()
}
fun getUsers(): LiveData<List<User>> {
return users
}
private fun loadUsers() {
}
}
class MyActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
val model: MyViewModel by viewModels()
model.getUsers().observe(this, Observer<List<User>>{ users ->
// update UI
})
}
}
활동이 다시 생성 MyViewModel 되면 첫 번째 활동에서 생성된 것과 동일한 인스턴스를 받습니다. 소유자 활동이 완료되면 프레임워크는 리소스를 정리할 수 있도록 ViewModel 개체의 메서드를 호출합니다.
ViewModel은 보기 Lifecycle 또는 활동 컨테스트에 대한 참조 보유할 수 있는 클래스를 참조에 대해 알지 못하기 때무에 더 쉽게 커버하는 테스트를 작성할 수 있음을 의미합니다. 개체는 개체와 같은 일을 포함할 수 있습니다. 그라나 객체는 개체와 같은 수명 주기 인식 관찰 가능 항목의 변경 사항을 관찰해서는 안됩니다. 예를 들어 시스템 서비스를 찾기 위해 컨테스트가 필요한 경우 클래스를 확장하고 클래스가 extends이므로 생성자에서 수신하는 생성자를 가질 수 있습니다.
- 조각이 생성될 때마다가 아니라 생성될 단어 목록을 재설정해야 하므로 이러한 메서드는 블록에 있어야 합니다.
- 데이터를 처리하고 UI를 업데이트하기 위한 코드
- 클래스를 사용하여 구성 변경 후에도 살아남은 개체 ViewModelFactory를 인스턴스화하고 반환합니다.
- ViewModels범위 를 제공하는 유틸리티 클래스입니다 .
- 또는 a 의 기본값 ViewModelProvider은 생성자에 전달하여 얻을 수 있습니다.
- ViewModelProvider주어진 ViewModelStoreOwner을 ViewModels통해 생성하고 지정된 저장소 Factory에 보관합니다.
- 기존 ViewModel을 반환하거나 this 와 연결된 범위(일반적으로 조각 또는 활동)에 새 ViewModel을 만듭니다.
- 생성된 ViewModel은 주어진 범위와 연관되며 범위가 살아있는 한 유지됩니다(예: 활동인 경우 완료되거나 프로세스가 종료될 때까지)
public interface ViewModelStoreOwner {
/**
* Returns owned {@link ViewModelStore}
*
* @return a {@code ViewModelStore}
*/
@NonNull
ViewModelStore getViewModelStore();
}
View ModelStore를 소유한 범위입니다.
이 인터페이스 구현의 책임은 구성을 변경하는 동안 소유된 View ModelStore를 유지하고 이 범위가 삭제될 경우 ViewModelStore.clear()를 호출하는 것입니다.
- 1개 이상의 Fragment에서 데이터 공유시에 사용한다.
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInataceState)
val binding = MainActivityBinding.inflate(layoutInflater)
setContentView(binding.root)
}
}
class MainFragmentOne : Fragment() {
private val shaeredViewModel: SharedViewModel by activityViewModel()
// View 초기화
}
class MainFragmentTwo : Fragment() {
private val sharedViewModel: ShapredViewModel by activityViewModel()
// View 초기화
}
class SharedViewModel : ViewModel() {
// TODO..;
}
- Android Kotlin Fundamentals: 5.1 ViewModel
- Android Fragment 간의 ViewModel 공유하기
[Android] RecyclerView, DiffUtil (2) | 2022.09.13 |
---|---|
[설정]전역변수에 m붙일경우, get/set method에 'm'파라미터 안 붙게 만들기 (0) | 2015.11.16 |