LiveData是一个数据持有者类,它持有一个值并允许观察该值。与普通的可观察对象不同,LiveData服从应用程序组件的生命周期,因此观察者可以指定它应该服从的生命周期。如果Observer的Lifecycle处于STARTED或RESUMED状态,LiveData会认为Observer处于活动状态。publicclassLocationLiveDataextendsLiveData{privateLocationManagerlocationManager;privateSimpleLocationListenerlistener=newSimpleLocationListener(){@OverridepublicvoidonLocationChanged(Locationlocation){setValue(location);}};publicLocationLiveData(Contextcontext){locationManager=(LocationManager)context.getSystemService(Context.LOCATION_SERVICE);}@OverrideprotectedvoidonActive(){locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,0,0,listener);}@OverrideprotectedvoidonInactive(){locationManager.removeUpdates(listener);}}Location监控的实现有3个重要的部分:onActive():当LiveData有一个当观察者处于活动状态时调用此方法,这意味着它需要开始观察来自设备的位置更新。vonInactive():当LiveData没有任何活跃的观察者时调用此方法。由于没有观察者监听,因此没有理由保持与LocationManager的连接。这非常重要,因为保持连接会显着耗尽电池电量并且没有任何好处。setValue():调用此方法更新LiveData实例的值并将更改通知活动的观察者。新的LocationLiveData可以像这样使用://updateUI});}});}}请注意,addObserver()方法将LifecycleOwner作为第一个参数传递。这样做表明观察者应该绑定到Lifecycle,意思是:如果Lifecycle不活跃(STARTED或RESUMED),即使值改变也不会调用观察者。如果生命周期被销毁,观察者会自动移除。LiveData是生命周期感知的事实为我们提供了一种新的可能性:它可以在多个活动、片段等之间共享。为了保持实例简单,可以将其作为实例,如下所示:publicclassLocationLiveDataextendsLiveData{privatestaticLocationLiveDatasInstance;privateLocationManagerlocationManager;@MainThreadpublicstaticLocationLiveDataget(Contextcontext){if(sInstance==null){sInstance=newLocation.getApplication();}returnsInstance;}privateSimpleLocationListenerlistener=newSimpleLocationListener(){@OverridepublicvoidonLocationChanged(Locationlocation){setValue(location);}};privateLocationLiveData(Contextcontext){locationManager=(LocationManager)context.getSystemService(Context.LOCATION_SERVICE);}@OverrideprotectedvoidonActive(){locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,0,0,listener);}@OverrideprotectedvoidonInactive(){locationManager.removeUpdates(listener);}}现在片段可以像下面这样使用它:publicclassMyFragmentextendsLifecycleFragment{publicvoidonActivityCreated(BundlesavedInstanceState){Ustil(reultUserStat)->{如果(结果){LocationLiveData.get(getActivity()).observe(this,location->{//updateUI});}});}}观察MyLocationListener实例的fragment和activity可能有多个,LiveData可以统一管理,这样仅当其中任何一个可见(即活动)时才连接到系统服务LiveData具有以下优点:无内存泄漏:因为Observers绑定了自己的Lifecycle对象,当他们的Lifecycle被销毁时,它们会自动清除。活动停止时不会崩溃:如果观察者生命周期处于空闲状态(例如,当活动在后台时),它们将不会收到更改事件。Alwayskeepdata***:如果Lifecycle重启(例如:activity从后台返回到start状态)会收到***位置数据(除非还没有)。妥善处理配置更改:如果由于配置更改(例如:设备轮换)而重新创建活动或片段,它将立即接收最新的有效位置数据。资源共享:只保留一个MyLocationListener实例,只连接一个系统服务,正确支持应用中的所有观察者。不再需要手动生命周期管理:片段只在需要时观察数据,不用担心被停止或停止后开始观察。由于片段在观察数据时会提供其生命周期,因此LiveData会自动管理所有这些。LiveData的转换有时可能需要在将LiveData发送给观察者之前更改其值,或者从另一个LiveData返回不同的LiveData实例。Lifecycle包提供了一个Transformations类,其中包含用于这些操作的辅助方法。,%20android.arch.core.util.FunctionLiveDatauserLiveData=...;LiveDatauserName=Transformations.map(userLiveData,user->{user.name+""+user.lastName});,%20android.arch.core.util.FunctionprivateLiveDatagetUser(Stringid){...;}LiveDatauserId=...;LiveDatauser=Transformations.switchMap(userId,id->getUser(ID));使用这些转换允许在整个调用链中携带观察者的生命周期信息,以便仅在观察者观察到LiveData的返回时才计算这些转换。转换的这种惰性性质允许隐式交付与生命周期相关的行为,而无需添加显式调用或依赖项。每当您认为您的ViewModel中需要一个Lifecycle类时,转换可能就是解决方案。例如:假设有一个UI,用户在其中输入地址并收到该地址的邮政编码。UI简单ViewModel可能如下所示:在这个实现中,每次调用getPostalCode()时,UI需要先从之前的LiveData注销并重新注册到新实例。此外,如果重新创建UI,它将触发新的repository.getPostCode()调用,而不是使用上一次调用的结果。你不能那样做,而应该实现将地址输入转换为邮政编码信息。classMyViewModelextendsViewModel{privatefinalPostalCodeRepositoryrepository;privatefinalMutableLiveDataaddressInput=newMutableLiveData();publicfinalLiveDatapostalCode=Transformations.switchMap(addressInput,(address)->{returnrepository.getPostCode(address).});publicMyViewrepositoryRepository(=repository}(privatevoidsetInput)){addressInput.setValue(address);}}请注意,我们甚至将postalCode字段设置为publicfinal,因为它永远不会更改。postalCode被定义为addressInput的转换,因此当addressInput更改时,如果有一个活跃的观察者,存储库。getPostCode()将被调用。如果调用时没有观察者处于活动状态,则在添加观察者之前不会执行任何计算。这种机制允许以更少的资源按需延迟创建LiveData。ViewModel可以轻松获取LiveData并在其上定义转换规则.创建新的转换应用程序中可能会使用十几种不同的特定转换plication,但默认情况下不提供。您可以使用MediatorLiveData实现您自己的转换,它是专门为正确侦听其他LiveData实例并处理它们发出的事件而创建的。MediatorLiveData需要特别注意将其活动/空闲状态正确传递给源LiveData。有关详细信息,请参阅转换类。