1,什么是viewmodel
1),在日常开发中,一般比较简单的页面都会全部写在activity或fragment中,稍微复杂点的都会用mvp来写.viewmodel从字面上看的工作就是维护view和model之间的数据交换,我愚昧的觉得就是类似mvp的p层.google那边给出的介绍说viewmodel就是view和model之间的桥梁.
2,viewmodel两大特性
1,数据操作不受activity或fragment生命周期影响,并activity销毁时系统回调viewmodel的onCleared()方法
2,可以容易在activity和fragment之间通信
1),接入viewmodel
implementation 'androidx.lifecycle:lifecycle-viewmodel:2.2.0'
2),相关代码
a,创建继承viewmodel的子类CounterViewModel
public class CounterViewModel extends ViewModel {
/***
* 对应的activity销毁时系统会调用此方法
*/
@Override
protected void onCleared() {
super.onCleared();
}
}
继续补全代码:
public class CounterViewModel extends ViewModel {
private Timer timer;
private int count=60;
private onCountChangeListenner mOnCountChangeListenner;
public void start(){
Log.i("viewmodel_tag","开始计时");
timer=new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
count--;
if (mOnCountChangeListenner!=null){
mOnCountChangeListenner.countChange(count);
}
if (count<=0){
timer.cancel();
}
}
},1000,1000);
}
public interface onCountChangeListenner{
void countChange(int count);
}
public void setOnCountChangeListenner(onCountChangeListenner mOnCountChangeListenner) {
this.mOnCountChangeListenner = mOnCountChangeListenner;
}
/***
* 对应的activity销毁时系统会调用此方法
*/
@Override
protected void onCleared() {
super.onCleared();
Log.i("viewmodel_tag","onCleared");
timer.cancel();
mOnCountChangeListenner=null;
}
}
CounterViewModel 中有个start方法启动计时器开始计时,并通过onCountChangeListenner将计时回调,在onCleared时取消timer
b,在activity中调用
public class ViewModelActivity extends AppCompatActivity {
private Button btn_start;
private TextView tv_show;
private CounterViewModel counterViewModel;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_view_model);
btn_start=(Button)findViewById(R.id.btn_start);
tv_show=(TextView) findViewById(R.id.tv_show);
initViewModel();
}
private void initViewModel() {
counterViewModel=new ViewModelProvider(this).get(CounterViewModel.class);
counterViewModel.setOnCountChangeListenner(new CounterViewModel.onCountChangeListenner() {
@Override
public void countChange(int count) {
Log.i("viewmodel_tag","countChange :"+count);
tv_show.setText("剩余"+count+"秒");
}
});
btn_start.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
counterViewModel.start();
}
});
}
@Override
public void onConfigurationChanged(@NonNull Configuration newConfig) {
super.onConfigurationChanged(newConfig);
Log.i("viewmodel_tag","onConfigurationChanged");
}
@Override
public void onBackPressed() {
super.onBackPressed();
Log.i("viewmodel_tag","放回键退出应用");
}
}
通过一句代码,便可创建实例,很方便
counterViewModel=new ViewModelProvider(this).get(CounterViewModel.class);
设置监听后并点击btn_start按钮开始计时,期间会旋转屏幕,观察日志打印
很明显,屏幕旋转并不影响计时操作,生命周期重走没有让counterViewModel重新实例化,重新start计时.最后双击返回键退出应用也走了onCleared()函数