这几个库理论上应该都会使用, 我认为属于JetPack中的基础库, 早期称为ArchitectureComponent, 后被并入Jetpack组件库之中.php
androidx内置LiveData/ViewModel/Lifecycle, 无需导入依赖.html
LiveData: 感知活跃(onStart)和非活跃状态(onPause)的数据观察者java
ViewModel: 屏幕旋转自动保存数据, 或者意外销毁读写saveInstance数据android
Lifecyle: 能够监听生命周期, 默认Activity和Fragment已经实现lifecyclegit
参考文献github
ViewModel只能在屏幕旋转时保存数据, 而没法在内存回收Activity时保存数据(除非使用SavedState)框架
ViewModel
用于继承实现自定义的数据实体
ViewModelStore
存储多个ViewModel的存储类, 开发者无需关心
ViewModelStoreOwner
Fragment|Activity都属于其派生类. 在ViewModelProvider建立时使用.
ViewModelProvider
用于建立ViewModel
建立ViewModule
public class LiveDataTimerViewModel extends ViewModel {
/**/ } 复制代码
使用
绑定生命周期同时返回一个ViewModel实例
ViewModelProvider(this,ViewModelProvider.AndroidViewModelFactory(application)).get(T::class.java) 复制代码
ViewModel有个覆写函数, 用于提供依附的ViewModelStoreOwner销毁是清理数据(设置对象为NULL/解绑监听器等)
protected void onCleared ()
复制代码
默认的AppCompatActivity
就实现了LifeCycleOwner
和ViewModelStoreOwner
public class ComponentActivity extends androidx.core.app.ComponentActivity implements LifecycleOwner, ViewModelStoreOwner, SavedStateRegistryOwner, OnBackPressedDispatcherOwner {
//...
}
复制代码
同时Fragment
也实现了ViewModelStoreOwner
ViewModel绑定生命周期的对象必须实现ViewModelStoreOwner
. 该接口的职责是保存ViewModelStore对象.
咱们能够经过实现该接口自定义
public interface ViewModelStoreOwner {
/** * Returns owned {@link ViewModelStore} * * @return a {@code ViewModelStore} */
@NonNull
ViewModelStore getViewModelStore();
}
复制代码
ViewModelStore
能够看作一个HashMap集合存储ViewModel的类, 能够建立对象
public final void clear() // 会触发全部ViewModel对象的onClear函数. 该函数中通常用于ViewModel是否某些内存 复制代码
ViewModel必须经过该类建立对象
val model = ViewModelProvider(this, ViewModelProvider.NewInstanceFactory()).get<Model>()
复制代码
构造函数
public ViewModelProvider (ViewModelStoreOwner owner, ViewModelProvider.Factory factory) public ViewModelProvider (ViewModelStore store, ViewModelProvider.Factory factory) 复制代码
使用方法
<T extends ViewModel> T get(Class<T> modelClass) <T extends ViewModel> T get(String key, Class<T> modelClass) 复制代码
该类用于覆写函数建立ViewModel的实例对象
查看默认的NewInstanceFactory源码能够看到
public static class NewInstanceFactory implements Factory {
@SuppressWarnings("ClassNewInstance")
@NonNull
@Override
public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
//noinspection TryWithIdenticalCatches
try {
return modelClass.newInstance(); // 经过反射建立对象
} catch (InstantiationException e) {
throw new RuntimeException("Cannot create an instance of " + modelClass, e);
} catch (IllegalAccessException e) {
throw new RuntimeException("Cannot create an instance of " + modelClass, e);
}
}
}
复制代码
有时候你的数据属于网络请求过来的数据实体, 这个时候就须要用构造器来
AndroidViewModel
该类用于建立ViewModel实例的时候调用其构造函数(具有参数Application), 让ViewModel中可使用Application
查看源码:
@NonNull
@Override
public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
if (AndroidViewModel.class.isAssignableFrom(modelClass)) {
//noinspection TryWithIdenticalCatches
try {
// 经过具有参数Applicaiton的构造函数使用反射建立对象
return modelClass.getConstructor(Application.class).newInstance(mApplication);
} catch (NoSuchMethodException e) {
throw new RuntimeException("Cannot create an instance of " + modelClass, e);
} catch (IllegalAccessException e) {
throw new RuntimeException("Cannot create an instance of " + modelClass, e);
} catch (InstantiationException e) {
throw new RuntimeException("Cannot create an instance of " + modelClass, e);
} catch (InvocationTargetException e) {
throw new RuntimeException("Cannot create an instance of " + modelClass, e);
}
}
return super.create(modelClass);
}
复制代码
onSaveInstanceState 和 ViewModel 区别
ViewModel本质上和onSaveIntance有区别.
ViewModel能够保存复杂大量数据, onSaveIntance基于Bundle对象保存不能存储大量数据(抛出异常)
ViewModel没法在乎外销毁时恢复数据, 只是配置变动(切换横竖屏)时数据依然存在
须要额外扩展依赖
implementation 'androidx.lifecycle:lifecycle-viewmodel-savedstate:1.0.0-alpha05'
复制代码
绑定全部者的时候使用SavedStateVMFactory
工厂实例
mSavedStateViewModel = ViewModelProviders.of(this, new SavedStateVMFactory(this))
.get(SavedStateViewModel.class);
复制代码
ViewModel须要建立一个构造函数
public class SavedStateViewModel extends ViewModel {
// 自定义的构造函数
public SavedStateViewModel(SavedStateHandle savedStateHandle) {
mState = savedStateHandle; // mState便可以读写数据, 不须要你去处理生命周期
}
}
复制代码
SavedStateHandle
可以保存和查询数据. 数据会和onSaveInstanse保存机制同样不会丢失.
public <T> MutableLiveData<T> getLiveData(@Nullable String key)
public Set<String> keys()
public <T> T get(@NonNull String key)
public <T> void set(@NonNull String key, @Nullable T value)
public boolean contains(@NonNull String key)
public <T> T remove(@NonNull String key)
复制代码
个人开源框架Net框架支持快速建立ViewModel
val model = getViewModel<Model>() // 仅仅配置变动数据恢复的
val model = getSavedModel<Model>() // 支持onSaveIntance意外销毁恢复数据的
复制代码
Model
class Model(saved: SavedStateHandle) : SavedViewModel(saved) {
var name: String?
get() = saved.get("name")
set(value) {
saved["name"] = value
}
}
复制代码
提供一个SavedViewModel类用于快速继承, saved即用于保存和恢复数据的存储对象
若是不想介入Net, 能够参考源码
open class SavedViewModel(var saved: SavedStateHandle) : ViewModel()
inline fun <reified M : ViewModel> ViewModelStoreOwner.getViewModel(): M {
return ViewModelProvider(this).get(M::class.java)
}
inline fun <reified M : ViewModel> FragmentActivity.getSavedModel(): M {
return ViewModelProvider(
this,
SavedStateViewModelFactory(application, this)
).get(M::class.java)
}
inline fun <reified M : ViewModel> Fragment.getSavedModel(): M {
return ViewModelProvider(
this,
SavedStateViewModelFactory(activity!!.application, this)
).get(M::class.java)
}
复制代码
使数据变成一个可被观察状态, 而且符合视图的生命周期.
在活跃状态观察者能够接受到事件, 不活跃状态观察者不会接收到事件. 若是生命周期全部者被破坏自动删除观察者.
活跃状态即非onPause
或者onDestroy
IllegalArgumentException
继承关系
java.lang.Object
↳ androidx.lifecycle.LiveData<T>
↳ androidx.lifecycle.MutableLiveData<T>
↳ androidx.lifecycle.MediatorLiveData<T>
复制代码
所有公开方法
T getValue() // 返回当前值 boolean hasActiveObservers() // 是否有被激活的观察者(处于活跃状态) boolean hasObservers() // 是否有观察者 void observe(LifecycleOwner owner, Observer<T> observer) void observeForever(Observer<T> observer) // 添加一个永远处于活跃状态的观察者(而且不会自动删除观察者), 因此须要你本身删除观察者 // 重复添加同一个观察者会抛出IllegalArgumentException void removeObserver(Observer<T> observer) // 删除观察者 void removeObservers(LifecycleOwner owner) // 删除拥有同一个生命周期全部者的全部观察者 复制代码
提供覆写函数
protected void onInactive ()
protected void onActive ()
protected void postValue (T value)
protected void setValue (T value)
复制代码
这是一个抽象类, 咱们通常都是用他的子类MutableLiveData<T>
建立MutableLiveData
// 建立对象
var data = MutableLiveData<String>()
// 设置值
data.value = "设计师"
// 设置观察者
data.observe(this@MainActivity, Observer {
Log.d("日志", "(MainActivity.kt:28) ___ it = $it")
})
复制代码
AppCompatActivity
自己就是实现了LifeCycleOwner
因此我这里直接传入This在数据变化后调用方法设置值(根据所处线程不一样而调用不一样的方法)
// 主线程
data.value = "设计师"
// 异步线程
data.postValue("设计师")
复制代码
若是在观察者以前设置值则设置观察者以后会受到你设置以前最后一次设置的值, 注意最后一次.
这个继承自liveData(abstract). 只是public
两个私有方法(原本是protected
)
所有源码:
public class MutableLiveData<T> extends LiveData<T> {
@Override
public void postValue(T value) {
super.postValue(value);
}
@Override
public void setValue(T value) {
super.setValue(value);
}
}
复制代码
LiveData能够存在多个观察者
咱们能够模仿MutableLiveData
本身自定义LiveData的逻辑
public class MyLiveData extends LiveData<String> {
/** * 活跃状态 */
@Override protected void onActive() {
super.onActive();
}
/** * 非活跃状态 */
@Override protected void onInactive() {
super.onInactive();
}
}
复制代码
要想触发这两个方法必需要绑定观察者.
其实实现LifecycleObserver
自己也可以实现生命周期的回调.
可是LiveData能够能够监听值变化 (其实Kotlin也能)而且根据生命周期自动取消观察者.
Transformations
提供两个函数, 他的功能相似RxJava的map
和flatMap
操做符, 转换LiveData的数据.
static <X, Y> LiveData<Y> map(LiveData<X> source, Function<X, Y> func) static <X, Y> LiveData<Y> switchMap(LiveData<X> trigger, Function<X, LiveData<Y>> func) 复制代码
map示例:
final MyLiveData myLiveData = new MyLiveData();
myLiveData.observe(this, new Observer<String>() {
@Override public void onChanged(@Nullable String s) {
}
});
final LiveData<Integer> transformationLiveData =
Transformations.map(myLiveData, new Function<String, Integer>() {
/** * 若是想要该方法回调须要结果LiveData设置观察者才行 * * @param input 源LiveData存储的数据 * @return 最终返回的LiveData存储的数据 */
@Override public Integer apply(String input) {
return 2;
}
});
transformationLiveData.observe(this, new Observer<Integer>() {
@Override public void onChanged(@Nullable Integer integer) {
}
});
复制代码
switchMap示例
final LiveData<Integer> transformationLiveData =
Transformations.switchMap(myLiveData, new Function<String, LiveData<Integer>>() {
/** * @param input 源数据 * @return 返回结果等于switchMap的结果 */
@Override public LiveData<Integer> apply(String input) {
MutableLiveData<Integer> transformationLiveData = new MutableLiveData<>();
transformationLiveData.setValue(3);
return transformationLiveData;
}
});
复制代码
总结:
二者区别即map返回的是一个类型, 而switchMap规定返回的是一个新的LiveData.
能够看作map能够替代switchMap, 由于MutableLiveData也是一个类型.
做为Transformation的参数传进去的LiveData若是以前就设置过Observer一样会生效, 至关于有两个观察者.
能够设置多个源LiveData
. 而后经过观察者来同时监听多个LiveData的变化
MediatorLiveData自己也是LiveData的一部分
<S> void addSource(LiveData<S> source, Observer<S> onChanged) // 添加源 <S> void removeSource(LiveData<S> toRemote) // 删除源 复制代码
示例
var data = MutableLiveData<String>()
var data2 = MutableLiveData<Int>()
// 这里就是在data,data2变动值时通知MediatorLiveData也更新
mediatorLiveData.addSource(data, Observer { mediatorLiveData.value = 1 })
mediatorLiveData.addSource(data2, Observer { mediatorLiveData.value = 3 })
mediatorLiveData.observe(this, Observer {
// data或data2属性变化都会在这里被监听
})
复制代码
关于LiveData的应用我认为只是针对应用后台和前台展现的应用场景
LiveData实现MVVM
有些人可能会说用LiveData来写MVVM, 可是我以为这有点扯淡了, LiveData只会在赋值对象的时候才会通知监听器, 对象中的属性变化并不会.
并且就算你为每一个数据都用LiveData写个监听器那也得在监听器中绑定UI, 这和本身每次设置UI有什么区别.
若是是对于ui的更新仍是推荐使用Databinding的数据绑定形式, 能够结合LiveData实现前台更新数据
binding = DataBindingUtil.setContentView<ActivityMainBinding>(this, layout)
binding.lifecycleOwner = this
binding.m = model
复制代码
Model
class Model{
val data = MutableLiveData<String>()
}
复制代码
XML
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools">
<data>
<variable name="m" type="com.example.architecture.Model" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity">
<TextView android:id="@+id/tv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@{m.data}" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
复制代码
这样Databinding更新属性就会具有LiveData的感知生命周期的功能, 只有处于前台才会当即更新ui.
Observable
和LiveData
区别
liveData还拥有官方的协程扩展库, 能够建立具有活跃状态的协程的做用域, 具体请查看个人协程文章: Kotlin协程: Coroutine/Channel/Flow 以及实际应用
生命周期组件, 能够将一个类赋予Activity生命周期.
实现接口LifecycleObserver
public class CusLifecycleObserver implements LifecycleObserver {}
复制代码
绑定生命周期
lifecycleOwner.getLifecycle().addObserver(this);
复制代码
而后就能够经过注解来在生命周期时自动调用
@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
void removeLocationListener() {
if (mLocationManager == null) {
return;
}
mLocationManager.removeUpdates(mListener);
mLocationManager = null;
Log.i("日志", "(BoundLocationListener.java:74) ___ removeLocationListener");
}
}
复制代码
全部的生命周期状态
public enum Event {
ON_CREATE,
ON_START,
ON_RESUME,
ON_PAUSE,
ON_STOP,
ON_DESTROY,
ON_ANY
}
复制代码
执行顺序
若是你想自定义LifecycleOwner也能够
public class MyActivity extends Activity implements LifecycleOwner {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mLifecycleRegistry = new LifecycleRegistry(this);
mLifecycleRegistry.markState(Lifecycle.State.CREATED);
}
@Override
public void onStart() {
super.onStart();
mLifecycleRegistry.markState(Lifecycle.State.STARTED);
}
@NonNull
@Override
public Lifecycle getLifecycle() {
return new LifecycleRegistry(this);
}
}
复制代码
这里我继承是Activity, 并不表明生命周期就只能是Activity的, 能够是任何具备生命周期的组件(官方同时支持Service的生命周期).
只有一个函数
public abstract Lifecycle getLifecycle ()
复制代码
这是控制生命周期状态变动的控制器
public void addObserver (LifecycleObserver observer) // 添加观察者 public void removeObserver (LifecycleObserver observer) // 删除观察者 public int getObserverCount () // 当前观察者数量 public Lifecycle.State getCurrentState () // 当前状态 public void markState (Lifecycle.State state) // 设置当前状态, 通常用户自定义LifecycleOwner使用 public void handleLifecycleEvent (Lifecycle.Event event) // 设置当前状态, 和markState不一样是这个若是参数状态和当前状态一直不会通知Observer观察者 复制代码
有五种状态
Lifecycle.State CREATED
Lifecycle.State DESTROYED
Lifecycle.State INITIALIZED
.
Lifecycle.State RESUMED
Lifecycle.State STARTED
复制代码
public boolean isAtLeast (Lifecycle.State state) // 若是当前声明周期大于等于参数生命周期则返回true public static Lifecycle.State valueOf (String name) // 将字符串转为State 复制代码
只能有一个或者没有参数, 可是能够增长一个LifecycleOwner
参数. 而且ON_ANY
注解的方法能够增长第二个注解Event
. 该参数的做用只是判断当前所处的生命周期.
class TestObserver implements LifecycleObserver {
@OnLifecycleEvent(ON_CREATE)
void onCreated(LifecycleOwner source) {}
@OnLifecycleEvent(ON_ANY)
void onAny(LifecycleOwner source, Event event) {}
}
复制代码
上面提到了用注解来控制生命周期, 若是你当前使用的JDK是JDK8以上能够选择覆写函数的形式来回调生命周期
不太推荐感受冗余
须要另外导入一个依赖:
dependencies {
// Java8 support for Lifecycles
implementation "android.arch.lifecycle:common-java8:1.0.0"
}
复制代码
而且再也不使用注解而是使用重写方法, 而且实现DefaultLifecycleObserver
class TestObserver implements DefaultLifecycleObserver {
@Override
public void onCreate(LifecycleOwner owner) {
// your code
}
}
复制代码