LiveData初次登场
Opened this issue · 0 comments
-
前言
其实在学习过程中一直有接触到,但是始终是似懂非懂。对这个组件也没有一个初步的定位和理解。
我第一次想用LiveData的时候是在学习Binding特性的时候。但是对于数据的变化可以由Observable 代劳,LiveData并不是唯一的选择。这样就会产生一个疑惑,那么LiveData是为Binding而生的吗,那么既然没有LiveData也可以做Binding。那么LiveData的真正价值在哪里。我回答不了这个问题。只能暂时搁置,暂缓使用。 -
LiveData出道
我在实际使用过程中出现这样的场景。我想要在某个ViewModel中执行跳转到其他Activity的Intent操作,但是这个操作是不被Android设计者鼓励的
- Intent的生成需要在Activity内执行,startActivity这个API本身就是Activity的成员函数
- ViewModel禁止拥有Activity的引用,MVVM界的共识,本身解耦分家的两个部件又搅合在一起,本身就是违法架构原则。其二,Activity的生命周期要比ViewModel要短,增加引用还会引起不必要的内存泄露
迫于无奈我只能写出这样别扭的诡异的代码
protected void onCreate(Bundle savedInstanceState) {
Logger.i( "---Create MainActivity----" );
super.onCreate(savedInstanceState);
HomeViewModel viewModel = new ViewModelProvider(this,
ViewModelProvider.AndroidViewModelFactory.getInstance(this.getApplication()))
.get(HomeViewModel.class);
ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
binding.setDatacontext( viewModel );
binding.searchButton.setOnClickListener( v -> {
Intent intent = new Intent(this, SearchActivity.class);
startActivity(intent);
} );
}
感觉就是革命不彻底的表现
LiveData终于横空出世
- 特性1 变化
LiveData 是一种可观察的数据存储器类。与常规的可观察类不同,LiveData 具有生命周期感知能力,意指它遵循其他应用组件(如 Activity、Fragment 或 Service)的生命周期。这种感知能力可确保 LiveData 仅更新处于活跃生命周期状态的应用组件观察者
这是数据变化,和个特性和Observable有重合
- 特性2 根据观察者生命周期推送,释放退订变化
如果观察者(由 Observer 类表示)的生命周期处于 STARTED 或 RESUMED 状态,则 LiveData 会认为该观察者处于活跃状态。LiveData 只会将更新通知给活跃的观察者。为观察 LiveData 对象而注册的非活跃观察者不会收到更改通知。
您可以注册与实现 LifecycleOwner 接口的对象配对的观察者。有了这种关系,当相应的 Lifecycle 对象的状态变为 DESTROYED 时,便可移除此观察者。这对于 Activity 和 Fragment 特别有用,因为它们可以放心地观察 LiveData 对象,而不必担心泄露(当 Activity 和 Fragment 的生命周期被销毁时,系统会立即退订它们)。
这个特性才是关键,这里已经很明确说了,就是为Activity 和 Fragment量身定做的,目的就是建立起UI Control层(Activity,Fragment)和ViewModel的联系
-
LiveData家族(相关Package)
dependencies {
def lifecycle_version = "2.2.0"
// ViewModel and LiveData
implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version"
// alternatively - just ViewModel
implementation "androidx.lifecycle:lifecycle-viewmodel:$lifecycle_version" // use -ktx for Kotlin
// alternatively - just LiveData
implementation "androidx.lifecycle:lifecycle-livedata:$lifecycle_version"
// alternatively - Lifecycles only (no ViewModel or LiveData). Some UI
// AndroidX libraries use this lightweight import for Lifecycle
implementation "androidx.lifecycle:lifecycle-runtime:$lifecycle_version"
annotationProcessor "androidx.lifecycle:lifecycle-compiler:$lifecycle_version" // use kapt for Kotlin
// alternately - if using Java8, use the following instead of lifecycle-compiler
implementation "androidx.lifecycle:lifecycle-common-java8:$lifecycle_version"
// optional - ReactiveStreams support for LiveData
implementation "androidx.lifecycle:lifecycle-reactivestreams:$lifecycle_version" // use -ktx for Kotlin
// optional - Test helpers for LiveData
testImplementation "androidx.arch.core:core-testing:$lifecycle_version"
}
-
LiveData使用示例
在build.gradle中添加
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
在MainViewModel.java中加入LiveData字段
private MutableLiveData<Class<?>> targetActivity;
public MutableLiveData<Class<?>> getTargetActivity() {
if( targetActivity == null )
targetActivity = new MutableLiveData<>();
return targetActivity;
}
泛型类代表传入显示Activity的类型
public void GoToRecognizeActivity()
{
this.targetActivity.setValue(RecognizeActivity.class);
}
按钮触发的逻辑就是设置LiveData的值,把要跳转的Activity类型通知出去
MainActivity.java中订阅LiveData
viewModel.getTargetActivity().observe(this, t->{
Intent intent = new Intent(this,t);
startActivity(intent);
});
这样清晰的多了,Activity里面还是做startActivity的事情,ViewModel管好业务和数据逻辑,大家各司其职。
-
LiveData的副产品 绑定通知
class ViewModelActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
// Inflate view and obtain an instance of the binding class.
UserBinding binding = DataBindingUtil.setContentView(this, R.layout.user);
// Specify the current activity as the lifecycle owner.
binding.setLifecycleOwner(this);
}
}
注意如果把 LiveData用做绑定需要加上 binding.setLifecycleOwner(this);