成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

谷歌官方Android應用架構庫——LiveData

移動開發 Android
LiveData 是一個數據持有者類,它持有一個值并允許觀察該值。不同于普通的可觀察者,LiveData 遵守應用程序組件的生命周期,以便 Observer 可以指定一個其應該遵守的 Lifecycle。

[[197255]]

LiveData 是一個數據持有者類,它持有一個值并允許觀察該值。不同于普通的可觀察者,LiveData 遵守應用程序組件的生命周期,以便 Observer 可以指定一個其應該遵守的 Lifecycle。

如果 Observer 的 Lifecycle 處于 STARTED 或 RESUMED 狀態,LiveData 會認為 Observer 處于活動狀態。

  1. public class LocationLiveData extends LiveData<Location> { 
  2.     private LocationManager locationManager; 
  3.  
  4.     private SimpleLocationListener listener = new SimpleLocationListener() { 
  5.         @Override 
  6.         public void onLocationChanged(Location location) { 
  7.             setValue(location); 
  8.         } 
  9.     }; 
  10.  
  11.     public LocationLiveData(Context context) { 
  12.         locationManager = (LocationManager) context.getSystemService( 
  13.                 Context.LOCATION_SERVICE); 
  14.     } 
  15.  
  16.     @Override 
  17.     protected void onActive() { 
  18.         locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, listener); 
  19.     } 
  20.  
  21.     @Override 
  22.     protected void onInactive() { 
  23.         locationManager.removeUpdates(listener); 
  24.     } 
  25.  

Location 監聽的實現有 3 個重要部分:

  • onActive():當 LiveData 有一個處于活動狀態的觀察者時該方法被調用,這意味著需要開始從設備觀察位置更新。
  • vonInactive():當 LiveData 沒有任何處于活動狀態的觀察者時該方法被調用。由于沒有觀察者在監聽,所以沒有理由保持與 LocationManager 的連接。這是非常重要的,因為保持連接會顯著消耗電量并且沒有任何好處。
  • setValue():調用該方法更新 LiveData 實例的值,并將此變更通知給處于活動狀態的觀察者。

可以像下面這樣使用新的 LocationLiveData:

  1. public class MyFragment extends LifecycleFragment { 
  2.     public void onActivityCreated (Bundle savedInstanceState) { 
  3.         LiveData<Location> myLocationListener = ...; 
  4.         Util.checkUserStatus(result -> { 
  5.             if (result) { 
  6.                 myLocationListener.addObserver(this, location -> { 
  7.                     // update UI 
  8.                 }); 
  9.             } 
  10.         }); 
  11.     } 
  12.  

請注意,addObserver() 方法將 LifecycleOwner 作為***個參數傳遞。這樣做表示該觀察者應該綁定到 Lifecycle,意思是:

  • 如果 Lifecycle 不處于活動狀態(STARTED 或 RESUMED),即使該值發生變化也不會調用觀察者。
  • 如果 Lifecycle 被銷毀,那么自動移除觀察者。

LiveData 是生命周期感知的事實給我們提供了一個新的可能:可以在多個 activity,fragment 等之間共享它。為了保持實例簡單,可以將其作為單例,如下所示:

  1. public class LocationLiveData extends LiveData<Location> { 
  2.     private static LocationLiveData sInstance; 
  3.     private LocationManager locationManager; 
  4.  
  5.     @MainThread 
  6.     public static LocationLiveData get(Context context) { 
  7.         if (sInstance == null) { 
  8.             sInstance = new LocationLiveData(context.getApplicationContext()); 
  9.         } 
  10.         return sInstance; 
  11.     } 
  12.  
  13.     private SimpleLocationListener listener = new SimpleLocationListener() { 
  14.         @Override 
  15.         public void onLocationChanged(Location location) { 
  16.             setValue(location); 
  17.         } 
  18.     }; 
  19.  
  20.     private LocationLiveData(Context context) { 
  21.         locationManager = (LocationManager) context.getSystemService( 
  22.                 Context.LOCATION_SERVICE); 
  23.     } 
  24.  
  25.     @Override 
  26.     protected void onActive() { 
  27.         locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, listener); 
  28.     } 
  29.  
  30.     @Override 
  31.     protected void onInactive() { 
  32.         locationManager.removeUpdates(listener); 
  33.     } 
  34.  

現在 fragment 可以像下面這樣使用它:

  1. public class MyFragment extends LifecycleFragment { 
  2.     public void onActivityCreated (Bundle savedInstanceState) { 
  3.         Util.checkUserStatus(result -> { 
  4.             if (result) { 
  5.                 LocationLiveData.get(getActivity()).observe(this, location -> { 
  6.                    // update UI 
  7.                 }); 
  8.             } 
  9.         }); 
  10.   } 
  11.  

可能會有多個 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

  1. LiveData<User> userLiveData = ...; 
  2. LiveData<String> userName = Transformations.map(userLiveData, user -> { 
  3.     user.name + " " + user.lastName 
  4. });  

,%20android.arch.core.util.Function

  1. private LiveData<User> getUser(String id) { 
  2.   ...; 
  3.  
  4. LiveData<String> userId = ...; 
  5. LiveData<Useruser = Transformations.switchMap(userId, id -> getUser(id) );  

使用這些轉換允許在整個調用鏈中攜帶觀察者的 Lifecycle 信息,以便只有在觀察者觀察到 LiveData 的返回時才運算這些轉換。轉換的這種惰性運算性質允許隱式的傳遞生命周期相關行為,而不必添加顯式的調用或依賴。

每當你認為在 ViewModel 中需要一個 Lifecycle 類時,轉換可能是解決方案。

例如:假設有一個 UI,用戶輸入一個地址然后會收到該地址的郵政編碼。該 UI 簡單的 ViewModel 可能像這樣:

  1. class MyViewModel extends ViewModel { 
  2.     private final PostalCodeRepository repository; 
  3.     public MyViewModel(PostalCodeRepository repository) { 
  4.        this.repository = repository; 
  5.     } 
  6.  
  7.     private LiveData<String> getPostalCode(String address) { 
  8.        // DON'T DO THIS 
  9.        return repository.getPostCode(address); 
  10.     } 
  11.  

如果是像這種實現,UI 需要先從之前的 LiveData 注銷并且在每次調用 getPostalCode() 時重新注冊到新的實例。此外,如果 UI 被重新創建,它將會觸發新的 repository.getPostCode() 調用,而不是使用之前的調用結果。

不能使用那種方式,而應該實現將地址輸入轉換為郵政編碼信息。

  1. class MyViewModel extends ViewModel { 
  2.     private final PostalCodeRepository repository; 
  3.     private final MutableLiveData<String> addressInput = new MutableLiveData(); 
  4.     public final LiveData<String> postalCode = 
  5.             Transformations.switchMap(addressInput, (address) -> { 
  6.                 return repository.getPostCode(address); 
  7.              }); 
  8.  
  9.   public MyViewModel(PostalCodeRepository repository) { 
  10.       this.repository = repository 
  11.   } 
  12.  
  13.   private void setInput(String address) { 
  14.       addressInput.setValue(address); 
  15.   } 
  16.  

請注意,我們甚至使 postalCode 字段為 public final,因為它永遠不會改變。postalCode 被定義為 addressInput 的轉換,所以當 addressInput 改變時,如果有處于活動狀態的觀察者,repository.getPostCode() 將會被調用。如果在調用時沒有處于活動狀態的觀察者,在添加觀察者之前不會進行任何運算。

該機制允許以較少的資源根據需要惰性運算來創建 LiveData。ViewModel 可以輕松獲取到 LiveData 并在它們上面定義轉換規則。

創建新的轉換

在應用程序中可能會用到十幾種不同的特定轉換,但是默認是不提供的。可以使用 MediatorLiveData 實現自己的轉換,MediatorLiveData 是為了用來正確的監聽其它 LiveData 實例并處理它們發出的事件而特別創建的。MediatorLiveData 需要特別注意正確的向源 LiveData 傳遞其處于活動/閑置狀態。有關詳細信息,請參閱 Transformations 類。 

責任編輯:龐桂玉 來源: Android開發中文站
相關推薦

2019-10-11 09:38:56

谷歌Android開發者

2017-05-25 12:30:44

AndroidApp開發架構

2011-02-17 13:35:12

ADT 9.0.0ADT下載ADT安裝

2011-03-17 08:58:09

數據儲存Data StoragAndroid API

2012-04-25 22:58:36

2011-09-05 14:02:53

Android視頻教程

2025-02-28 16:58:00

2017-06-30 09:36:10

Android OAPI兼容

2010-02-06 15:32:30

Android架構

2011-03-07 09:33:37

2010-02-06 15:53:55

2017-11-28 11:19:55

SDN架構驅動

2010-02-06 15:26:11

Android應用程序

2012-02-03 09:14:44

谷歌惡意應用Android

2011-03-31 09:16:39

Android Mar付費

2011-10-25 09:58:39

谷歌Android Mar

2011-02-18 14:02:36

Android R5 Android NDKAndroid NDK

2022-03-04 15:44:45

MVI 架構LiveData代碼

2011-07-22 13:32:33

Android Mar谷歌應用商店

2011-12-06 21:36:48

Android
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 成人在线免费视频观看 | 国产精品一区二区免费 | 亚洲精品一区二区三区中文字幕 | 91精品国产91久久久久久密臀 | 久久丝袜| 黄色国产大片 | 久久久精品网站 | 日本污视频 | 日韩欧美视频网站 | 亚洲欧美日韩在线不卡 | 成人一区二区在线 | 国产露脸对白88av | 国产精品免费看 | 免费的av| 乱码av午夜噜噜噜噜动漫 | 三级黄视频在线观看 | 国产欧美日韩一区 | 国产中文字幕av | 国产亚洲二区 | 亚洲国产欧美一区 | 久久久久国产一区二区三区四区 | 一级毛片在线播放 | 久久久亚洲综合 | 亚洲精品国产电影 | 精品久久久久久红码专区 | 久久久综合精品 | 在线日韩 | 黄色男女网站 | 爱综合| 欧美黄在线观看 | 成人免费看片又大又黄 | 最新国产精品 | 精品久久影院 | 国产一区二区三区在线免费观看 | 午夜精品久久久久久久久久久久久 | 欧美二三区 | 中文字幕国 | 成年人精品视频 | 亚洲一区二区在线视频 | 小视频你懂得 | 欧美区在线 |