ViewMode+LiveData总结
Activity/Fragment只应关注UI,而不应关系操作逻辑,因此操作逻辑应放到Viewmodel中去
下面是我手画的数据流图:
首先有Fragment
、ViewModel
、Livedata
这三个对象。
- Fragment观察Viewmodel的Livedata数据,如果livedata的值改变会通知Frament。
- ViewModel获取数据(网络、数据库),然后设置Livedata的值
- Livedata的值改变就通知Fragment
- Fragment刷新界面
代码如下:
Fragment
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.widget.TextView;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.lifecycle.Observer;
/**
*
* @date 2020/9/19
*/
public class MyActivity extends AppCompatActivity {
Handler messageHandler;
MyViewModel myViewModel;
Handler mainHandler;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final TextView textView = findViewById(R.id.textView);
// 新建ViewModel
myViewModel = new MyViewModel();
// 子线程
HandlerThread handlerThread = new HandlerThread("");
handlerThread.start();
// 子线程Handler
messageHandler = new Handler(handlerThread.getLooper());
// 主线程handler
mainHandler = new Handler(getMainLooper());
// 开启自自线程改变数据
messageHandler.post(new Runnable() {
@Override
public void run() {
int i = 0;
while (i < 100) {
mainHandler.post(new Runnable() {
@Override
public void run() {
myViewModel.requestChangeText();
}
});
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
i++;
}
}
});
myViewModel.getmText().observe(this, new Observer<String>() {
@Override
public void onChanged(final String s) {
runOnUiThread(new Runnable() {
@Override
public void run() {
textView.setText(s);
}
});
}
});
}
}
viewmodel
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
import java.util.Observable;
import java.util.Random;
/**
* Describe:<p></p>
* 描述:<p></p>
*
* @date 2020/9/19
*/
public class MyViewModel extends ViewModel implements IMyModelHelper {
private MutableLiveData<String> mText = new MutableLiveData<String>();
public MyViewModel() {
}
public MutableLiveData<String> getmText() {
return mText;
}
@Override
public void requestChangeText() {
changeText();
}
private void changeText(){
getmText().setValue(new Random(10).toString());
}
}
package com.loyal888.tets;
/**
* Describe:<p></p>
* 描述:<p></p>
*
* @date 2020/9/19
*/
public interface IMyModelHelper {
void requestChangeText();
}
总结:数据通知可以使用Observer,实现进一步解耦合
MVP 和MVVM的区别
获取VidewModel实例
// 新建ViewModel
myViewModel = ViewModelProviders.of(this).get(MyViewModel.class);
VideoModel的生命周期
系统首次调用 Activity 对象的 onCreate() 方法时请求 ViewModel。系统可能会在 Activity 的整个生命周期内多次调用 onCreate(),如在旋转设备屏幕时。ViewModel 存在的时间范围是从您首次请求 ViewModel 直到 Activity 完成并销毁。
在当前生命周期为Destrory的时候,清除了
mViewModelStore
ViewModel中使用Context
扩展AndroidViewModel
ViewModel 对象可以包含 LifecycleObservers,如 LiveData 对象。但是,ViewModel 对象绝不能观察对生命周期感知型可观察对象(如 LiveData 对象)的更改。 如果 ViewModel 需要 Application 上下文(例如,为了查找系统服务),它可以扩展 AndroidViewModel 类并设置用于接收 Application 的构造函数,因为 Application 类会扩展 Context。
ViewModel源码分析
1. ViewModelProvider.of(this)
- 检查应用的上下文
- 构造了AndroidViewModelFactory
- 返回provider
public static ViewModelProvider of(@NonNull FragmentActivity activity) {
return of(activity, null);
}
@NonNull
@MainThread
public static ViewModelProvider of(@NonNull FragmentActivity activity,
@Nullable Factory factory) {
// 1. 检查应用的上下文且必须是application
Application application = checkApplication(activity);
if (factory == null) {
// 2.构造了AndroidViewModelFactory
factory = ViewModelProvider.AndroidViewModelFactory.getInstance(application);
}
// 3.返回provider
// 3.1 注意这里的activity.getViewModelStore()
return new ViewModelProvider(activity.getViewModelStore(), factory);
}
2. activity.getViewModelStore()
public ViewModelStore getViewModelStore() {
if (getApplication() == null) {