The foreword 0.

In order to help developers build a good APP, Google has made great efforts to introduce various project architecture ideas such as MVP,MVVM, etc. to help developers develop more efficiently. However, Google has introduced a new project architecture to give developers more choices. As for the merits of this architectural approach and frameworks like MVP, you may decide after reading this article.

1. Life cycle

Developing software on a mobile operating system can be very complicated, because we have to deal with the unpredictable actions of the system and users at any time, and often things don’t go the way we want them to. So the system gives us something like a life cycle of the core components to tell us what state our APP is in so we can do something about it.

As shown above. Although Google gives a very detailed life cycle structure for activities, we make appropriate arrangements according to the life cycle, such as adding and removing real-time GPS position listeners:

However, with the increasing complexity of the business, we may need to verify some user information to the server before adding listeners, and wait for the returned information to be correct before listening for location. It is difficult to know the life cycle state of the current activity during asynchronous network callbacks.

If this happens, we may never be able to remove the associated resources. This is just the tip of the iceberg, as you can imagine what can happen when our asynchronous calls face unpredictable user actions and system processing.

In short, because we don’t know the real-time state of the UI, we can’t handle the data and logic perfectly. This is the root cause of similar hidden trouble is not well solved.

2. Google Goodies

This time, Google launched a new set of project architecture components and architecture ideas, from UI to Data, to help us develop our APP more accurately.

2.1 Core: Lifecycle Components

Lifecycle Components are used to manage the Lifecycle of UI controller (Activity/Freagment), which is convenient to query the status of the current component Lifecycle.

The query status is as follows:

There are two specific ways of use:

  • Inheritance LifecycleActivity/LifecycleFragment can
  • Implement the LifecycleRegistryOwner interface yourself

java

// By inheritance, Lifecycle Components manage their Lifecycle. public class MainActivity extends LifecycleActivity { }Copy the code

So how do we use it?

// By extending LifecycleObserver, Public Class MyTest implements LifecycleObserver {private Lifecycle Lifecycle; Public MyTest(Lifecycle){Lifecycle. AddObserver (this); // Lifecycle contains the Lifecycle of the current component. this.lifecycle=lifecycle; } // This method is called @onlifecycleEvent (Lifecycle.event.on_resume) public void when onResume occursresume(){
        Log.i("TAG"."it called when resume ");
    }

    public void doTest(String s){// You can query the current UI state at any timeif(lifecycle.getCurrentState().equals(Lifecycle.State.RESUMED)){
            Log.i("TAG"."resume");
        }else{
            Log.i("TAG"."is not resume !! "); } } } public class MainActivity extends LifecycleActivity { @Override protected void onCreate(Bundle savedInstanceState)  { super.onCreate(savedInstanceState);setContentView(R.layout.activity_main); MyTest MyTest =new MyTest(this.getlifecycle ()); MyTest MyTest =new MyTest(this.getlifecycle ()); }}Copy the code

You’ll be happy to see that with this component, we have the ability to use the Activity as a UI controller, just to display the UI and corresponding user actions, minimizing the size of the Activity. Don’t worry, there’s more to the package.

3. The ViewModel and LiveData

  • The ViewModel is a placeholder for UI-related data, and it clears its own data when all relevant UIs have finished.
  • LiveData is an Observable life-cycle aware component that holds concrete data (much like an Observable in RxJava that follows the lifecycle of the component).

The relationship between them is that the ViewModel is responsible for managing the different LiveData and providing it to the UI.

3.1 LiveData

We can talk about LiveData first. Since it is already aware of the lifecycle, this means that we do not need to query the current LIFECYCLE of the UI, and since it is observable, this means that when the data it holds changes, the observer is immediately informed. The most important methods of LiveData are as follows:

OnActive () // onInactive() is called when LiveData currently has more than one active observer // Is called when LiveData currently has no active observersetValue() // Don't be afraid to change the current data so that observers can be exposed to the changed data. Observe (LifecycleOwner owner, Observer<T> Observer)Copy the code

There is a concept of an active observer, which we might as well put behind. LiveData can be used as follows:

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 voidonActive() {
        locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, listener);
    }

    @Override
    protected void onInactive() { locationManager.removeUpdates(listener); } } public class MainActivity extends LifecycleActivity { @Override protected void onCreate(Bundle savedInstanceState) {  super.onCreate(savedInstanceState);setContentView(R.layout.activity_main); LiveData<Location> myLocationListener = new LocationLiveData(); /* * observe(LifecycleOwner owner, Observer<T> Observer) * LiveData will be judged LifecycleOwner * to the current incoming observer is active (that is, the UI is visible) * / myLocationListener. Observe (this, New Observer<Location>() {@override public void onChanged(@nullable Location Location)setWhen Value() modifs the data, // this will be the modified data}}); }}Copy the code

Ok, that’s the basic usage of LiveData. Thanks to LiveData, our data is much more “smart”. When the UI is not visible, the changed data is not updated to the UI.

And if the data is used in different UIs, we can also have a singleton LiveData to provide unified data for different UIs. I won’t go into the details of these operations.

Now looking back at LiveData, we find that it has at least the following advantages:

  • Memory leaks can be avoided: due to the Observer and Lifecycle binding, the Observer is automatically cleaned up when Lifecycle is destroyed.
  • Avoid crashes caused by updating data after the Activity has been destroyed
  • Shareable data
  • Data updates smarter: When data is updated while it is not visible on the UI, the latest data is updated to the UI when it is visible again.
  • No additional lifecycle events need to be handled in the Activity

A racing boat!

3.2 the ViewModel

The ViewModel is simpler because it temporarily stores UI-related data and ensures that it will be saved even if the Activity configuration changes and is recreated.

The basic usage is as follows:

Public class MyViewModel extends ViewModel {// MyViewModel extends ViewModel {private MutableLiveData<List<User>> Users; public LiveData<List<User>>getUsers() {
        if (users == null) {
            users = new MutableLiveData<List<Users>>();
            loadUsers();
        }
        return users;
    }

    private void loadUsers() {
        // doasync operation to fetch users } } public class MyActivity extends AppCompatActivity { public void onCreate(Bundle SavedInstanceState) {// Get the ViewModel via ViewModelProviders // The user gets the ViewModel attached to the Activity. MyViewModel = ViewModelProviders.of(this).get(MyViewModel.class); model.getUsers().observe(this, users -> { // update UI }); }}Copy the code

This is the most basic use of the ViewModel, which is responsible for getting data from all over the place, and then loading that data into LiveData and feeding it to the UI; Viewmodels can also be shared among different fragments, but I won’t go into that here.

Because the ViewModel itself is bound to the Activity /fragment lifecycle, the ViewModel cleans its data only when the UI controller bound to it is destroyed.

As is shown in

4. Data persistence: Room

Room is a solution of SQLite ORM provided by Google. In fact, there is no big difference between Room and other ORM frameworks in essence. There is not much new, so it only gives the general architecture diagram, and students who are interested can learn by themselves

5. To summarize

Let’s go back and look at the architecture

In fact, the most interesting part is the UI-ViewModel. This architecture can help us to do at least a few things:

  • The UI is really separate from the Data
  • Asynchronous invocation and logic control can be more refined (because of more awareness of the lifecycle)
  • Implement a Model-driven UI

6. Errata

no

The appendix

Android’s official website: developer.android.com/topic/libra…