[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