Android Official architecture Components introduction of Livedata (ii)

Source: Internet
Author: User

Livedata

LiveDatais one for holding data and supporting data can be monitored (observed). Unlike the observed in the traditional observer pattern, Livedata is a 生命周期感知 component, so the observer can designate one LifeCycle to Livedata and listen to the data.

If the Observer specifies LifeCycle in Started or RESUMED state, Livedata treats the observer as active and notifies them of changes in the data.

Let's look at a piece of code:

 Public classLocationlivedataextendsLivedata<location> {    PrivateLocationmanager Locationmanager; PrivateSimplelocationlistener listener =NewSimplelocationlistener () {@Override Public voidonlocationchanged (location) {setValue);    }    };  PublicLocationlivedata (Context context) {Locationmanager=(Locationmanager) Context.getsystemservice (Context.location_service); } @Overrideprotected voidonactive () {locationmanager.requestlocationupdates (Locationmanager.gps_provider,0, 0, listener); } @Overrideprotected voidoninactive () {locationmanager.removeupdates (listener); }}

There are three noteworthy places:

    • Onactive ()

When this method is called, the number of observers representing Livedata has changed from 0 to 1, and for our position monitoring, we should register our time monitoring.

    • Oninactive ()

When this method is called, the number of observers representing Livedata becomes 0, and since there is no observer, there is no reason to listen again, so we should remove the location listener.

    • SetValue ()

This method is called to update the Livedata data and to notify the active observer.

Then we can use the Locationlivedata as follows.

 public  class  myfragment extends   lifecyclefragment { public  void   onactivitycreated (Bundle savedinstancestate) {livedata  <Location> myloc        Ationlistener = ...; Util.checkuserstatus (Result -> if< /span> (Result) {Mylocationlistener.addobserver ( this , location-> { /            /  update UI  });    }        }); }}

Note the above addObserver method, which we will LifeCycleOwner pass in as the first parameter, which means that our locationlivedata will follow the lifecycle of this fragment.

    • If lifecycle is not in either started or resumed, then the observer will not be able to accept the callback for the data update, even if the data has changed.
    • If the lifecycle is destroyed, that is, the end of the life cycle, the observer will be automatically removed from the Livedata.

Since Locationlivedata is life-cycle aware, we can change its code slightly so that it can be shared by multiple activity or fragment:

 Public classLocationlivedataextendsLivedata<location> {    Private StaticLocationlivedata sinstance; PrivateLocationmanager Locationmanager; @MainThread Public StaticLocationlivedata Get (Context context) {if(Sinstance = =NULL) {sinstance=NewLocationlivedata (Context.getapplicationcontext ()); }        returnsinstance; }    PrivateSimplelocationlistener listener =NewSimplelocationlistener () {@Override Public voidonlocationchanged (location) {setValue);    }    }; PrivateLocationlivedata (Context context) {Locationmanager=(Locationmanager) Context.getsystemservice (Context.location_service); } @Overrideprotected voidonactive () {locationmanager.requestlocationupdates (Locationmanager.gps_provider,0, 0, listener); } @Overrideprotected voidoninactive () {locationmanager.removeupdates (listener); }}

The reason for using a singleton here is to have multiple activity or fragment share a Locationlivedata instance.
Then we can use this:

 public  class  myfragment extends   lifecyclefragment { public  void   onactivitycreated (Bundle savedinstancestate) {util.checkuserstatus (Result -& Gt  { if   (res Ult) {Mylocationlistener.get (Getactivity ()). Addobserver ( this , L ocation-> { //  update UI  });  }        }); }}

With this change, it can now be managed gracefully even with multiple activity or fragment using Locationlivedata. Don't bother about page destruction.

Summarize some of the livedata a bit:

    • No memory overflow

When the viewer is bound to their corresponding lifecycle, they are automatically overrun when the page is destroyed, without causing a memory overflow.

    • does not cause crash due to the invisible activity

When activity is not visible, Livedata does not notify the observer even if there are data changes. Because at this time the Observer's Lifecyele is not in the started or resumed state.

    • Changes in configuration

When the current activity configuration changes (such as the screen orientation), it causes the oncreate to go through again, which is the latest data that the viewer will receive immediately before the configuration changes.

    • Resource sharing

We only need a locationlivadata, connect the system service once, can support all observers.

    • No more human life cycle processing

As you can see from the code above, our activity or fragment as long as we need to observe the data to observe the data, do not need to ignore the life cycle changes. All of this is given to Livedata for automatic management.

Conversion of Livedata

Sometimes there is a need to change the type of data before Livedata notifies the observer of the changed data, or to return a different livedata.

Here is a class Transformations that can help with these operations.

    • Transformations.map ()

Before the change of the Livedata data is passed to the observer, a method is applied on the data:

livedata<user> userlivedata = ...; Livedata<String> userName = Transformations.map (userlivedata, user, {    + "" +  User.lastname});

If we just need to know the name of the changing user, we can just observe the Livedata object of username. It extracts the user name from the Userlivedata data and passes it to its own observer.

    • Transformations.switchmap ()

Similar to Transformations.map (), except that the method of passing a switchmap () must return a Livedata object.

Private Livedata<user> GetUser (String id) {  ...;} Livedata<String> userId = ...; Livedata<User> User = Transformations.switchmap (userid, ID, getUser (ID));

When you consider using Lifecycle objects in ViewModel, this conversion is an optional solution.
If there is a demand, the user input an address, we update the address on the screen of the ZIP code, the simple wording as follows:

 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); }}

This is obviously a serious problem, and when the Getpostalcode method is called, the UI code needs to perform a registered observer operation on the return value of the Getpostalcode and remove the previous observer, which is obviously inefficient. Also, if the UI is rebuilt because of a change in configuration (screen rotation), it triggers a call to Getpostalcode again instead of using the previous invocation result.

So we can do the following conversions:

classMyviewmodelextendsViewModel {Private Finalpostalcoderepository repository; Private FinalMutablelivedata<string> Addressinput =NewMutablelivedata ();  Public FinalLivedata<string> PostalCode =Transformations.switchmap (addressinput, address)- {                returnRepository.getpostcode (address);  });  PublicMyviewmodel (postalcoderepository repository) { This. Repository =Repository}Private voidSetInput (String address) {Addressinput.setvalue (address); }}

Note that here we write the PostalCode access limiter as public final because it will always be the same, and the UI simply registers the observer with PostalCode when it is needed. This is when the user calls SetInput, and if there is an active observer on the PostalCode, then Repository.getpostcode (address) is called, and if there are no active observers at this time, Then Repository.getpostcode (address) is not called.

Custom transformations

In your application, you may need to convert more livedata than the above two, you can use the class to implement these transformations, MediatorLiveData which can be used to correctly handle the changes of events in many other livedata and to handle these events. Mediatorlivedata will active/inactive pass its state changes correctly to the Livedata it handles, such as MEDIATORLIVEDATA without the observer.

This article turns from https://www.cnblogs.com/zqlxtt/p/6887940.htm

Android Official architecture Components introduction of Livedata (ii)

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.