您好,登錄后才能下訂單哦!
本篇內容主要講解“Android LiveData的優點有哪些”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“Android LiveData的優點有哪些”吧!
LiveData 是一個數據持有者類,它持有一個值并允許觀察該值。不同于普通的可觀察者,LiveData 遵守應用程序組件的生命周期,以便 Observer 可以指定一個其應該遵守的 Lifecycle。
如果 Observer 的 Lifecycle 處于 STARTED 或 RESUMED 狀態,LiveData 會認為 Observer 處于活動狀態。
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); } }
Location 監聽的實現有 3 個重要部分:
onActive():當 LiveData 有一個處于活動狀態的觀察者時該方法被調用,這意味著需要開始從設備觀察位置更新。
vonInactive():當 LiveData 沒有任何處于活動狀態的觀察者時該方法被調用。由于沒有觀察者在監聽,所以沒有理由保持與 LocationManager 的連接。這是非常重要的,因為保持連接會顯著消耗電量并且沒有任何好處。
setValue():調用該方法更新 LiveData 實例的值,并將此變更通知給處于活動狀態的觀察者。
可以像下面這樣使用新的 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 作為***個參數傳遞。這樣做表示該觀察者應該綁定到 Lifecycle,意思是:
如果 Lifecycle 不處于活動狀態(STARTED 或 RESUMED),即使該值發生變化也不會調用觀察者。
如果 Lifecycle 被銷毀,那么自動移除觀察者。
LiveData 是生命周期感知的事實給我們提供了一個新的可能:可以在多個 activity,fragment 等之間共享它。為了保持實例簡單,可以將其作為單例,如下所示:
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); } }
現在 fragment 可以像下面這樣使用它:
public class MyFragment extends LifecycleFragment { public void onActivityCreated (Bundle savedInstanceState) { Util.checkUserStatus(result -> { if (result) { LocationLiveData.get(getActivity()).observe(this, location -> { // update UI }); } }); } }
可能會有多個 fragment 和 activity 在觀察 MyLocationListener 實例,LiveData 可以規范的管理它們,以便只有當它們中的任何一個可見(即處于活動狀態)時才連接到系統服務。
LiveData 有以下優點:
沒有內存泄漏:因為 Observer 被綁定到它們自己的 Lifecycle 對象上,所以,當它們的 Lifecycle 被銷毀時,它們能自動的被清理。
不會因為 activity 停止而崩潰:如果 Observer 的 Lifecycle 處于閑置狀態(例如:activity 在后臺時),它們不會收到變更事件。
始終保持數據***:如果 Lifecycle 重新啟動(例如:activity 從后臺返回到啟動狀態)將會收到***的位置數據(除非還沒有)。
正確處理配置更改:如果 activity 或 fragment 由于配置更改(如:設備旋轉)重新創建,將會立即收到***的有效位置數據。
資源共享:可以只保留一個 MyLocationListener 實例,只連接系統服務一次,并且能夠正確的支持應用程序中的所有觀察者。
不再手動管理生命周期:fragment 只是在需要的時候觀察數據,不用擔心被停止或者在停止之后啟動觀察。由于 fragment 在觀察數據時提供了其 Lifecycle,所以 LiveData 會自動管理這一切。
LiveData 的轉換
有時候可能會需要在將 LiveData 發送到觀察者之前改變它的值,或者需要更具另一個 LiveData 返回一個不同的 LiveData 實例。
Lifecycle 包提供了一個 Transformations 類包含對這些操作的幫助方法。
,%20android.arch.core.util.Function
LiveData<User> userLiveData = ...; LiveData<String> userName = Transformations.map(userLiveData, user -> { user.name + " " + user.lastName });
,%20android.arch.core.util.Function
private LiveData<User> getUser(String id) { ...; } LiveData<String> userId = ...; LiveData<User> user = Transformations.switchMap(userId, id -> getUser(id) );
使用這些轉換允許在整個調用鏈中攜帶觀察者的 Lifecycle 信息,以便只有在觀察者觀察到 LiveData 的返回時才運算這些轉換。轉換的這種惰性運算性質允許隱式的傳遞生命周期相關行為,而不必添加顯式的調用或依賴。
每當你認為在 ViewModel 中需要一個 Lifecycle 類時,轉換可能是解決方案。
例如:假設有一個 UI,用戶輸入一個地址然后會收到該地址的郵政編碼。該 UI 簡單的 ViewModel 可能像這樣:
class MyViewModel extends ViewModel { private final PostalCodeRepository repository; public MyViewModel(PostalCodeRepository repository) { this.repository = repository; } private LiveData<String> getPostalCode(String address) { // DON'T DO THIS return repository.getPostCode(address); } }
如果是像這種實現,UI 需要先從之前的 LiveData 注銷并且在每次調用 getPostalCode() 時重新注冊到新的實例。此外,如果 UI 被重新創建,它將會觸發新的 repository.getPostCode() 調用,而不是使用之前的調用結果。
不能使用那種方式,而應該實現將地址輸入轉換為郵政編碼信息。
class MyViewModel extends ViewModel { private final PostalCodeRepository repository; private final MutableLiveData<String> addressInput = new MutableLiveData(); public final LiveData<String> postalCode = Transformations.switchMap(addressInput, (address) -> { return repository.getPostCode(address); }); public MyViewModel(PostalCodeRepository repository) { this.repository = repository } private void setInput(String address) { addressInput.setValue(address); } }
請注意,我們甚至使 postalCode 字段為 public final,因為它永遠不會改變。postalCode 被定義為 addressInput 的轉換,所以當 addressInput 改變時,如果有處于活動狀態的觀察者,repository.getPostCode() 將會被調用。如果在調用時沒有處于活動狀態的觀察者,在添加觀察者之前不會進行任何運算。
該機制允許以較少的資源根據需要惰性運算來創建 LiveData。ViewModel 可以輕松獲取到 LiveData 并在它們上面定義轉換規則。
創建新的轉換
在應用程序中可能會用到十幾種不同的特定轉換,但是默認是不提供的。可以使用 MediatorLiveData 實現自己的轉換,MediatorLiveData 是為了用來正確的監聽其它 LiveData 實例并處理它們發出的事件而特別創建的。MediatorLiveData 需要特別注意正確的向源 LiveData 傳遞其處于活動/閑置狀態。有關詳細信息,請參閱 Transformations 類。
到此,相信大家對“Android LiveData的優點有哪些”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。