关于ViewModel来说,其实还是蛮简单的。从ViewModel官方的描述来看ViewModel的存在,解决了俩大问题:
1.1、解决问题1
我们都知道,当我们的Activity/Fragment因为某些因素被销毁重建时,我们的成员变量便失去了意义。因此我们常常需要通过 onSaveInstanceState()和onCreate()/onSaveInstanceState(Bundle)完成对数据的恢复(通常还要保证其正确的序列化)。并且对于大型数据来书,便有些乏力,比如:List、Bitmap…
而ViewModel就是解决此问题。
1.2、解决问题2
另一个问题是Activity/Fragment经常需要进行一些异步操作。一旦涉及到异步,我们都明白这里存在内存泄漏的可能性。因此我们保证Activity/Fragment在销毁后及时清理异步操作,以避免潜在的内存泄漏。
ViewModel并没有自动帮我们解决这个问题,而是通过onCleared()交给我们业务自己重写去处理。
1.3、使用
build.gradle:
implementation "android.arch.lifecycle:extensions:1.1.1"
TimerViewModel.java
package com.jxd.studyone.viewmodel;
import android.util.Log;
import androidx.lifecycle.ViewModel;
import java.util.Timer;
import java.util.TimerTask;
public class TimerViewModel extends ViewModel
{
private String TAG = this.getClass().getName();
private Timer timer;
private int currentSecond;
/**
* 开始计时
* */
public void startTiming()
{
if (timer == null)
{
currentSecond = 0;
timer = new Timer();
TimerTask timerTask = new TimerTask()
{
@Override
public void run()
{
currentSecond++;
if(onTimeChangeListener != null)
{
onTimeChangeListener.onTimeChanged(currentSecond);
}
}
};
timer.schedule(timerTask, 1000, 1000);//延迟3秒执行
}
}
/**
* 通过接口的方式,完成对调用者的通知,这种方式不是太好,更好的方式是通过LiveData组件来实现
* */
public interface OnTimeChangeListener
{
void onTimeChanged(int second);
}
private OnTimeChangeListener onTimeChangeListener;
public void setOnTimeChangeListener(OnTimeChangeListener onTimeChangeListener)
{
this.onTimeChangeListener = onTimeChangeListener;
}
/**
* 由于屏幕旋转导致的Activity重建,该方法不会被调用
*
* 只有ViewModel已经没有任何Activity与之有关联,系统则会调用该方法,你可以在此清理资源
* */
@Override
protected void onCleared()
{
super.onCleared();
Log.d(TAG, "onCleared()");
timer.cancel();
}
}
ViewModelActivity.java
package com.jxd.studyone.viewmodel;
import androidx.appcompat.app.AppCompatActivity;
import androidx.lifecycle.ViewModelProviders;
import android.os.Bundle;
import android.widget.TextView;
import com.jxd.studyone.R;
public class ViewModelActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_view_model);
iniComponent();
}
private void iniComponent()
{
final TextView tvTime = findViewById(R.id.tv_time);
//通过ViewModelProviders得到ViewModel,如果ViewModel不存在就创建一个新的,如果已经存在就直接返回已经存在的
TimerViewModel timerViewModel = ViewModelProviders.of(this).get(TimerViewModel.class);
timerViewModel.setOnTimeChangeListener(new TimerViewModel.OnTimeChangeListener()
{
@Override
public void onTimeChanged(final int second)
{
//更新UI界面
runOnUiThread(new Runnable()
{
@Override
public void run()
{
tvTime.setText("TIME:" + second);
}
});
}
});
timerViewModel.startTiming();
}
}
可以看到的是,当屏幕旋转时,数据并没有收到影响。
版权声明:本文为u012539700原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。