关于ViewModel 介绍,文章不过多阐述。官方文档html
本文将从三个方面作必定阐述java
你须要处理配置变化android
orientation = portrait
,可是你没法禁止用户去改变语言、文字大小。这样就可能会致使Activity被移除或者从新建立为何onSaveInstanceState
依旧不够git
传统的作法都是在配置发生变化即 onSaveInstanceState
方法去save data, 在onCreate去restore datagithub
可是这里有两个限制api
onSaveInstanceState
方法不可以缓存较大的数据,笔者以前尝试缓存上百兆数据发现抛出了TransactionTooLargeException
serializable
或者 Parceable
, 可是有时候这些数据来自第三方库,咱们不能修改它,对于某些场景,很难在onSaveonSaveInstanceState
中保存数据基于上述两点,ViewModel应运而生缓存
- 配置改变先后数据存储与恢复
public class ZeroViewModel extends ViewModel {
public User user;
}
复制代码
public class ZeroDemo extends AppCompatActivity {
private TextView tv;
private ZeroViewModel vm;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tv_btn);
tv = findViewById(R.id.tv_simple);
vm = ViewModelProviders.of(this).get(ZeroViewModel.class);
System.out.println("szw vm.user = " + vm.user);
}
// android:onClick="onClickSimpleButton"
public void onClickSimpleButton(View v) {
vm.user = new User(23, "jorden");
}
}
复制代码
旋转屏幕,vm.user 依旧 != null网络
public class SameClass01 extends AppCompatActivity {
private TextView tv;
private ZeroViewModel vm;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tv_btn);
tv = findViewById(R.id.tv_simple);
vm = ViewModelProviders.of(this).get(ZeroViewModel.class);
System.out.println("szw SameClass01 : " + vm.user);
}
// launch the second instance
// android:onClick="onClickSimpleButton"
public void onClickSimpleButton(View v) {
vm.user = new User(100, "SuperMario");
startActivity(new Intent(this, SameClass01.class));
}
}
复制代码
即便有两个同类的Activity实例,第一个vm.user 持有的依旧是Mario,第二个vm.user 持有null . 这符合笔者的预期oracle
public class SameClass02 extends AppCompatActivity {
private TextView tv;
private ZeroViewModel vm;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tv_btn);
tv = findViewById(R.id.tv_simple);
vm = ViewModelProviders.of(this).get(ZeroViewModel.class);
System.out.println("szw SameClass02 onCreate() : " + vm.user);
}
// android:onClick="onClickSimpleButton"
public void onClickSimpleButton(View v) {
vm.user = new User(22, "test");
}
// android:onClick="onClickSimpleButton2"
public void onClickSimpleButton2(View v) {
System.out.println("szw SameClass02 : saved = "+vm.user);
}
}
复制代码
先启动SameClass02 ,执行onClickSimpleButton,finish从新打开,日志输出nullapp
上述两个例子表现正常
public class SameVm {
public static User user;
}
复制代码
public class ZeroDemo extends AppCompatActivity {
private TextView tv;
private ZeroViewModel vm;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tv_btn);
tv = findViewById(R.id.tv_simple);
String value = savedInstanceState == null ? "emptyBundle" : savedInstanceState.getString("key");
System.out.println("szw onCreate() " + value);
vm = ViewModelProviders.of(this).get(ZeroViewModel.class);
System.out.println("szw vm.user = " + vm.user);
System.out.println("szw static = "+SameVm.user);
}
// android:onClick="onClickSimpleButton"
public void onClickSimpleButton(View v) {
vm.user = new User(23, "jorden");
SameVm.user = new User(21, "king");
}
}
复制代码
旋转屏幕后,日志输出
szw vm.user = User{id=23, name='jorden'}
szw static = User{id=21, name='king’}
复制代码
Terminate Application
和1一样的操做
szw vm.user = null
szw static = null
复制代码
从上面两个例子,感受没什么不一样。他们都能缓存数据,终止应用程序都会被销毁
它们的不一样之处:
- ViewModel 主要是为了解耦,有点相似于MVP中的P,ViewModel 是MvvM中VM。你能在ViewModel中作异步操做(i.e访问网络),你能够改变data而且让View接受到通知LiveData
- static value 能被任何类修改,可是ViewModel 是Activity的私有变量,有点相似ThreadLocal
- ViewModel 能够判断Activity是正常销毁或者配置改变,进而作出不一样的响应,finish->removedata ,configurationchange->savedata,静态变量却不能
onSaveInstanceState
方法源码以下
public class DupliViewModel extends ViewModel {
private SingleLiveEvent<String> message = new SingleLiveEvent<>();
public void fetchMessage(){
message.setValue("A New Value");
}
public LiveData<String> getMessage() {
return message;
}
}
复制代码
public class DupliObserverDemo extends AppCompatActivity {
private TextView tv;
private DupliObserverDemo self;
private DupliViewModel vm;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tv_btn);
self = this;
tv = findViewById(R.id.tv_simple);
vm = ViewModelProviders.of(this).get(DupliViewModel.class);
vm.getMessage().observe(this, new Observer<String>() {
@Override
public void onChanged(@Nullable String s) {
System.out.println("szw updated ~");
Toast.makeText(self, "updated "+s, Toast.LENGTH_SHORT).show();
}
});
}
// android:onClick="onClickSimpleButton"
public void onClickSimpleButton(View v) {
vm.fetchMessage();
}
}
复制代码