[Android] Live Data
LiveData 는 값을 유지하고, 이 값이 observed 상태를 갖게 해주는 data holder 클래스이다.
일반적인 Observerble과 달리 LiveData는 앱 컴포넌트의 라이프 사이클을 따른다.
LiveData를 안드로이드 프로젝트에 import하는 방법은 adding components to your project
LiveData는 Observer의 라이프 사이클이STARTED
또는RESUMED
상태일 때만 Observer를 활성화 상태로 여긴다.
Location Sample
public class LocationLiveData extends LiveData<Location> {
private LocationManager locationManager;
private SimpleLocationListener listener = new SimpleLocationListener() {
@Override
public void onLocationChanged(Location location) {
setValue(location);
}
};
public LocationLiveData(Context context) {
locationManager = (LocationManager) context.getSystemService(
Context.LOCATION_SERVICE);
}
@Override
protected void onActive() {
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, listener);
}
@Override
protected void onInactive() {
locationManager.removeUpdates(listener);
}
}
onActive()
- LiveData가 active observer를 가지고 있을 때 호출된다.
디바이스의 location 업데이트 정보 observing을 시작한다는 의미이다.
- LiveData가 active observer를 가지고 있을 때 호출된다.
onInactive()
- LiveData가 active observer를 더이상 가지지 않을 때 호출된다.
어떤 observer도 없으니 LocationManager 서비스와 연결상태를 유지할 필요가 없다.
이러한 연결을 유지하는 것은 불필요하게 배터리를 소모하기 때문에 중요한 부분이다.
- LiveData가 active observer를 더이상 가지지 않을 때 호출된다.
setValue()
- LiveData의 값을 업데이트하고 active observer들에게 변화를 알려주는 메소드이다.
위의 Sample LocationLiveData 사용 예
public class MyFragment extends LifecycleFragment {
public void onActivityCreated (Bundle savedInstanceState) {
LiveData<Location> myLocationListener = ...;
Util.checkUserStatus(result -> {
if (result) {
myLocationListener.addObserver(this, location -> {
// update UI
});
}
});
}
}
addObserver()의 첫번째 파라미터로 LifecycleOwner를 전달한다.
이 observer가 LifecycleOwner의 라이프 사이클을 따른다는 것을 의미한다.
- 라이프 사이클이 active state(STARTED or RESUMED)가 아니라면, 값이 변경되어도 observer는 호출되지 않는다.
- 라이프 사이클이 destoryed 되면, observer는 자동으로 제거된다.
라이프 사이클 기반이라는 LiveData의 장점은 LiveData를 여러 액티비티, 프래그먼트 등 간에 공유할 수 있게 해준다.
LiveData를 singleton으로 만드는 예
public class LocationLiveData extends LiveData<Location> {
private static LocationLiveData sInstance;
private LocationManager locationManager;
@MainThread
public static LocationLiveData get(Context context) {
if (sInstance == null) {
sInstance = new LocationLiveData(context.getApplicationContext());
}
return sInstance;
}
private SimpleLocationListener listener = new SimpleLocationListener() {
@Override
public void onLocationChanged(Location location) {
setValue(location);
}
};
private LocationLiveData(Context context) {
locationManager = (LocationManager) context.getSystemService(
Context.LOCATION_SERVICE);
}
@Override
protected void onActive() {
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, listener);
}
@Override
protected void onInactive() {
locationManager.removeUpdates(listener);
}
}
프래그먼트에서 사용할 때는 :
public class MyFragment extends LifecycleFragment {
public void onActivityCreated (Bundle savedInstanceState) {
Util.checkUserStatus(result -> {
if (result) {
LocationLiveData.get(getActivity()).observe(this, location -> {
// update UI
});
}
});
}
}
LiveData의 장점들
- No memory leaks
- Observer들이 각각 자신의 Lifecycle을 따르기 때문에 Lifecycle이 destroyed 될 때 그들은 자동으로 정리된다.
- No crashes due to stopped activities
- Observer의 Lifecycle 이 비활성화 상태인 경우(예, 액티비티가 back stack에 들어가는 경우), 그들은 변경 이벤트를 받지 않는다.
- Always up to date data
- Lifecycle이 재시작되는 경우(예, back stack에 있다가 다시 시작되는 경우), 가장 최신의 데이터를 받을 수 있다.
- Proper configuration change
- 액티비티나 프래그먼트가 configuration 변경으로 다시 만들어지는 경우(예, 디바이스 화면 회전), 즉시 최근의 유효한 데이터를 받게 된다.
- Sharing Resources
- LiveData를 singleton으로 유지할 수 있게 되었고, 시스템 서비스에 단 한번만 연결하면 되며, 앱 내의 모든 observer를 지원할 수 있게 되었다.
- No more manual lifecycle handling
- 이제 프래그먼트들은 필요할 때만 데이터를 observe 하며, 프래그먼트가 중지되었을 때 observing을 중지 / 시작할지 걱정하지 않아도 된다.
- 프래그먼트가 자신의 Lifecycle 을 observing 동안 제공하므로, LiveData는 자동으로 이 문제를 관리할 수 있다.
[참고]
Android developers
Comments