引入
正常情况下,如果一个进程被移到后台,且当前系统内存不足时,会有一定概率会将该进程杀死来释放内存资源,而被系统杀死时,ViewModel也会被删除,UI的数据就会遭到丢失。

如下图所示,一旦切出后台进程被系统杀死数据就会丢失。
不过好在系统杀死进程时,会调用 onSaveInstanceState() 方法,顾名思义就是保存实例状态的,我们重写这个方法来保存我们的数据。
代码
1. onSaveInstanceState
ViewModel部分
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| package com.example.viewmodelsavedstate;
import androidx.lifecycle.MutableLiveData; import androidx.lifecycle.ViewModel;
public class MyViewModel extends ViewModel { private MutableLiveData<Integer> number;
public MutableLiveData<Integer> getNumber() { if(number == null){ number = new MutableLiveData<>(); number.setValue(0); } return number; }
public void add(int x){ number.setValue(number.getValue() + x); } }
|
MainActivity,21 - 23行是载入 savedInstanceState,28 - 32是写入 savedInstanceState。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| package com.example.viewmodelsavedstate;
import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; import androidx.databinding.DataBindingUtil; import androidx.lifecycle.ViewModelProvider; import android.os.Bundle; import com.example.viewmodelsavedstate.databinding.ActivityMainBinding;
public class MainActivity extends AppCompatActivity { MyViewModel myViewModel; ActivityMainBinding binding; public final static String SAVED_KEY_NAME = "number";
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); binding = DataBindingUtil.setContentView(this, R.layout.activity_main); myViewModel = new ViewModelProvider(this).get(MyViewModel.class); if(savedInstanceState != null){ myViewModel.getNumber().setValue(savedInstanceState.getInt(SAVED_KEY_NAME)); } binding.setData(myViewModel); binding.setLifecycleOwner(this); }
@Override protected void onSaveInstanceState(@NonNull Bundle outState) { super.onSaveInstanceState(outState); outState.putInt(SAVED_KEY_NAME, myViewModel.getNumber().getValue()); } }
|
2. SavedStateHandle
ViewModel部分,使用 SavedStateHandle 来代替 MutableLiveData 存储数据,同时在创建 ViewModel 时将SavedStateHandle 传入供后续使用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| package com.example.viewmodelsavedstate;
import androidx.lifecycle.MutableLiveData; import androidx.lifecycle.SavedStateHandle; import androidx.lifecycle.ViewModel;
public class MyViewModel extends ViewModel { private SavedStateHandle handle; public MyViewModel(SavedStateHandle handle){ this.handle = handle; }
public MutableLiveData<Integer> getNumber() { if(!handle.contains(MainActivity.SAVED_KEY_NAME)){ handle.set(MainActivity.SAVED_KEY_NAME, 0); } return handle.getLiveData(MainActivity.SAVED_KEY_NAME); }
public void add(int x){ getNumber().setValue(getNumber().getValue() + x); } }
|
MainActivity部分
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| package com.example.viewmodelsavedstate;
import androidx.appcompat.app.AppCompatActivity; import androidx.databinding.DataBindingUtil; import androidx.lifecycle.ViewModelProvider;
import android.os.Bundle;
import com.example.viewmodelsavedstate.databinding.ActivityMainBinding;
public class MainActivity extends AppCompatActivity { MyViewModel myViewModel; ActivityMainBinding binding; public final static String SAVED_KEY_NAME = "number";
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); binding = DataBindingUtil.setContentView(this, R.layout.activity_main); myViewModel = new ViewModelProvider(this).get(MyViewModel.class); binding.setData(myViewModel); binding.setLifecycleOwner(this); }
}
|