全文阅读预计 10 分钟
这可能是你看过的最清晰明了的讲解
主题 👇
写在前面:由于
ViewModel
与LiveData
关联性强,在学习ViewModel
的时候要结合LiveData
同时学习
想要快速学习 LiveData ?请进入此链接学习我对于 LiveData 的快速及通俗讲解。 全文阅读预计 15 分钟。
官方定义:
ViewModel
类旨在以注重生命周期
的方式存储和管理界面相关的数据
。ViewModel
类让数据可在发生屏幕旋转等配置更改
后继续存在
问题来源(1):例如你的
APP
某个Activity
中包含一个列表
,因为配置更改而重新创建Activity
后(例如众所周知的屏幕旋转发生后需手动保存数据在旋转后进行恢复)
,新Activity
必须重新
提取列表数据,对于简单数据,Activity
可以使用onSaveInstanceState()
方法从onCreate()
中的捆绑包恢复数据,但这种方法仅适合可以序列化再反序列化但少量数据
,不适合数量可能较大但数据,如用户列表或位图
问题来源(2):我们通常需要调用网络接口数据,网络数据需要一段时间才能返回结果,而我们需要管理这些调用,并确保系统
销毁后清理这些调用
来避免内存泄漏
,项目内容的日益增多会使开发者花费大量时间进行维护,并且在因为配置更改重新创建对象的情况下(例如上面说的屏幕旋转的例子)
,会造成资源浪费,因为对象可能需要重新发出已经发出过的调用
所以,从界面控制器
(Activity、Fragment 等)
分离出试图数据所有权的做法更易行、高效且势在必行
使用 👇
引入 ViewModel
// build.gradle
dependencies {
// ViewModel and LiveData
def lifecycle_version = "2.1.0"
implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version"
// 或
// implementation "androidx.lifecycle:lifecycle-extensions:2.1.0"
// 前者创建一个变量主要是便于管理,假如说你还引入了 lifecycle 的其它东西那么他们都同时使用这个变量的版本号就好,以后升级版本的时候只需要改一个地方
}
需求实践
我们做一个模拟服务器获取一个列表数据并展示到
RecyclerView
上的例子
第一步:
// 创建一个 ViewModel 类
public class FourViewModel extends ViewModel {
private MutableLiveData<List<User>> users;
public LiveData<List<User>> getUserList() {
if (users == null) {
users = new MutableLiveData<>();
loadUsers();
}
return users;
}
private void loadUsers() {
// Handler 只为了模拟,你可以在这里通过你的网络框架 OkHttp、Retrofit 等进行网络操作
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
List<User> list = new ArrayList<>();
list.add(new User());
// ... 添加多个测试数据
list.add(new User());
users.setValue(list);
}
}, 2000);
}
}
第二步:
// 将 Activity 继承自 AppCompatActivity
public class FourActivity extends AppCompatActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
FourViewModel model = ViewModelProviders.of(this).get(FourViewModel.class);
model.getUserList().observe(this, new Observer<List<User>>() {
@Override
public void onChanged(List<User> users) {
// recyclerView.setLayoutManager...
// recyclerView.setAdapter...
}
});
}
}
ViewModel
是什么:它相当于界面控制器
的辅助程序类,负责为界面准备数据,在配置更改期间会自动保留ViewModel
对象,便于他们存储的数据立即可供下一个Activity、Fragment
实例使用。例如上面的例子
:如果您需要在应用中显示用户列表,请确保将获取和保留该用户列表的责任分配给ViewModel
而不是Activity、Fragment
!!!ViewModel 绝不能引用视图、Lifecycle 或可能存储对 Activity 上下文对引用对任何类!!!
ViewModel
对象存在的时间比视图或LifecycleOwners
的特定实例存在的时间更长。还意味着,你可以更轻松地编写涵盖ViewModel
的测试,因为它不了解视图和Lifecycle
对象。ViewModel
对象可以包含LifecycleObservers
,如LiveData
对象。但是,ViewModel
对象绝不能观察对生命周期感知型可观察对象(如LiveData
对象)的更改。 如果ViewModel
需要Application
上下文(例如,为了查找系统服务),它可以扩展AndroidViewModel
类并设置用于接收Application
的构造函数,因为Application
类会扩展Context
。
// 也就是说如果你想用 context 可以继承自 AndroidViewModel
// 就可以得到 Application 对象了再通过 Application 获取 context
public class FourViewModel extends AndroidViewModel {
public FourViewModel(@NonNull Application application) {
super(application);
// do something...
}
}
文末 👇
OK,到这里就是 ViewModel 入门讲解了,你会发现代码变多了,但是仔细想想,当我们接手别人项目的时候最难懂的是什么:是混乱的逻辑
。上面的代码量虽然多了一点,但使代码的逻辑变得清晰
了,何尝不是一件好事呢~
在此,你已经在极少对时间内对于 ViewModel
有了新的认识,现在我推荐你学习如何通过 MVVM框架
来编写以后的代码,它的优势是使你的代码逻辑更加清晰以减少开发时间。
想要快速学习 MVVM
框架?请进入此链接学习我对于 MVVM 的快速及通俗讲解。 全文阅读预计 10 分钟。
码字不易,还请动动小手左侧栏中点赞 👍,3Q