作用:
以注重生命周期的方式存储和管理界面相关(Activity/Fragment)的数据;ViewModel 始终与具有生命周期的组件(Activity/Fragment)关联创建,并且只要组件仍处于活跃状态就会保留数据。
ViewModel 能在配置变更时避免状态丢失。但如果 App 因为内存不足而被系统 kill 掉,此时 ViewModel 也会被清除。
注:ViewModel 只是用来管理 UI 的数据的,千万不要让它持有 View、Activity 或者 Fragment 的引用(小心内存泄露)。
生命周期
使用
// ViewModel
public class UserModel extends ViewModel {
private final MutableLiveData<User> userLiveData = new MutableLiveData<>();
public LiveData<User> getUser() {
return userLiveData;
}
public UserModel() {
// trigger user load.
}
void doAction() {
// depending on the action, do necessary business logic calls and update the
// userLiveData.
}
}
//在 Activity 中使用:
public class UserActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.user_activity_layout);
//构建 ViewModel 实例
final UserModel viewModel = new ViewModelProvider(this).get(UserModel.class);
//观察 ViewModel 中数据的变化,并实时展示
viewModel.getUser().observe(this, new Observer<User>() {
@Override
public void onChanged(@Nullable User data) {
// update ui.
}
});
findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//点击按钮,更新数据
viewModel.doAction();
}
});
}
}
ViewModel 也可以用作 Activity 的不同 Fragment 之间的通信层。每个 Fragment 都可以通过它们的 Activity 使用相同的键获取 ViewModel。这允许 Fragment 之间以解耦的方式进行通信,这样它们就不需要直接与另一个 Fragment 对话。
public class MyFragment extends Fragment {
public void onStart() {
UserModel userModel = new ViewModelProvider(requireActivity()).get(UserModel.class);
}
}
AndroidViewModel
是 ViewModel 的一个子类,多了个 Application,方便在 ViewModel 里面使用 Context。
public class AndroidViewModel extends ViewModel {
@SuppressLint("StaticFieldLeak")
private Application mApplication;
public AndroidViewModel(@NonNull Application application) {
mApplication = application;
}
/**
* Return the application.
*/
@SuppressWarnings("TypeParameterUnusedInFormals")
@NonNull
public <T extends Application> T getApplication() {
//noinspection unchecked
return (T) mApplication;
}
}