当前位置:网站首页>Jetpack family - ViewModel

Jetpack family - ViewModel

2022-06-23 08:13:00 Susceptible to cold

about Android The traditional way of coding , In a general way , Page UI To deal with , Data loading , All in Activity or Fragment In the middle of , But this is not enough “ Single function principle ”, It is not easy to maintain and expand . We should layer the project structure , Conventional MVC,MVP and MVVM, The project structure is divided into three layers ,“ A stall for each ”, These three models have their own characteristics 、 Each have advantages and disadvantages , But they all have one thing in common , Is to distinguish M Layer and V layer ,M namely Model layer ,V namely View layer ,M The layer is responsible for data processing ,View Layer responsibility UI The exhibition of , The difference lies in how M Layer and V Layer by layer .

among ,MVVM Mode addition M Layer and the V Outside the floor , Namely VM layer , namely ViewModel.

Jetpack For developers ViewModel The concept of , Transfer the data needed for the page from V Layer and the M Peel out of the layer ,ViewModel Is between View Layer and the Model A bridge on the floor , Make the view and data separate , And keep in touch .

Life cycle

When Android Return the application to the desktop , Or when the horizontal and vertical screens switch ,Activity Components such as may lose status or be destroyed , At this time , Developers usually need to consider the preservation and recovery of data , The common is through onSavaInstanceState() Methods and onRestoreInstanceState() Method to implement , With ViewModel, You can save data in a simpler way . Why is that ?

ViewModel Component independent configuration changes , in other words , When something special happens that leads to Activity When some lifecycles are re executed ,ViewModel The life cycle of does not change .

The picture below is ViewModel And Activity The life cycle of :

As can be seen from the above figure ,ViewModel Will be accompanied by Activity The entire life cycle , until Activity perform onDestroy() After method , Will clear.

Usage method

First step , Add dependency

// ViewModel
implementation 'androidx.lifecycle:lifecycle-viewmodel:2.2.0'

After creating MyViewModel class , Inherited from ViewModel:

class MyViewModel : ViewModel() {

    override fun onCleared() {
        super.onCleared()
        print("onCleared")
    }
}

You can see ,ViewModel Class has only one lifecycle method , That's it onCleared(), We usually need to release some resources in this method , Avoid memory leaks .

It should be noted that ,Activity The life cycle of is changing , They don't execute onCleared(). In order to prove Activity When executing each life cycle ,ViewModel It doesn't change , So we can ViewModel Use in Handler perhaps RxJava Do a timed loop task , observation Activity Will it affect ViewModel:

class MyViewModel : ViewModel() {

    var handler: Handler = object : Handler() {
        var i = 0
        override fun handleMessage(msg: Message) {
            super.handleMessage(msg)
            print(i++)
            sendEmptyMessageDelayed(0, 500)
        }
    }

    public fun startHandler() {
        handler.sendEmptyMessageDelayed(0, 500)
    }

    override fun onCleared() {
        super.onCleared()
        print("onCleared")
        handler.removeMessages(0)
    }
}

stay MyViewModel Use in Handler Created a regular rotation training task , Every time 500 Print the log in milliseconds . Next , stay Activity Created in ViewModel Instance object , Call its startHandler() Method start execution :

class ViewModelActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_view_model)

        val viewModel = ViewModelProvider(this).get(MyViewModel::class.java)
        viewModel.startHandler()
    }
}

Running code will find , When Activity When screen rotation occurs , The log is not interrupted , And the printed numbers are continuous , So prove it ViewModel Not subject to Activity Life cycle impact of .

The most important point is also introduced in the above code , That's it ViewModel Instance creation , First you need to create a ViewModelProvider Class object , Its construction method needs to pass in Activity example , stay androidx in ,FragmentActivity By default ViewModelStoreOwner Interface :

public class ComponentActivity extends androidx.core.app.ComponentActivity implements
        LifecycleOwner,
        ViewModelStoreOwner,
        HasDefaultViewModelProviderFactory,
        SavedStateRegistryOwner,
        OnBackPressedDispatcherOwner {

}

establish ViewModelProvider After the instance , Call its get() The method will do :

public class ViewModelStore {

    private final HashMap<String, ViewModel> mMap = new HashMap<>();

    final void put(String key, ViewModel viewModel) {
        ViewModel oldViewModel = mMap.put(key, viewModel);
        if (oldViewModel != null) {
            oldViewModel.onCleared();
        }
    }

    final ViewModel get(String key) {
        return mMap.get(key);
    }

    Set<String> keys() {
        return new HashSet<>(mMap.keySet());
    }

    /**
     *  Clears internal storage and notifies ViewModels that they are no longer used.
     */
    public final void clear() {
        for (ViewModel vm : mMap.values()) {
            vm.clear();
        }
        mMap.clear();
    }
}

get() The core of method is to call ViewModelStore Of get() Method , It can be seen that ViewModelStore Class is to use HashMap take ViewModel With its key(class name ) Save it .

other

It should be noted that , It is because of ViewModel Break away from Activity Life cycle of , It is not recommended to ViewModel In the middle of Context quote , To avoid memory leaks . But if ViewModel Must be used in Context What shall I do? , Can be ViewModel Class inherits from AndroidViewModel,AndroidViewModel Inherited from ViewModel, And receive Applcation Of Context.

ViewModel Will not suffer Actvity The impact of the life cycle , Is it possible to use ViewModel replace onSaveInstanceState() Methods? ?ViewModel and onSaveInstanceState() There are still differences ,onSaveInstanceState() Methods are generally used to store a small amount of state data , And it can persist , but ViewModel Theoretically, there is no size limit on the data , But when the page is completely destroyed ,ViewModel The data in no longer exists .

原网站

版权声明
本文为[Susceptible to cold]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/01/202201121641113267.html