架构库
LiveData
数据变更观察者, 我觉得和DataBinding的Observable接口发生冲突
ViewModel
解耦数据脱离组件, 防止意外销毁
Lifecyle
分离生命周期
Room
(推荐使用Realm替代, Reaml+RxJava可以替代Room+LiveData, 并且更加强大)
DataBinding
数据和Ui的双向绑定, 数据变更观察者
参考文献
框架开发指南
官方视频
参考
Demo
android-lifecycles : 关于lifecycle/viewModule/liveData的示例
android-architecture-components
Retrofit+Okhttp Dagger2
完整依赖
dependencies {
// ViewModel and LiveData
implementation "android.arch.lifecycle:extensions:1.0.0"
annotationProcessor "android.arch.lifecycle:compiler:1.0.0"
// Room
implementation "android.arch.persistence.room:runtime:1.0.0"
annotationProcessor "android.arch.persistence.room:compiler:1.0.0"
// Paging
implementation "android.arch.paging:runtime:1.0.0-alpha4-1"
// Test helpers for LiveData
testImplementation "android.arch.core:core-testing:1.0.0"
// Test helpers for Room
testImplementation "android.arch.persistence.room:testing:1.0.0"
}
lifecycle已被support library实现无需导入
dependencies {
// RxJava support for Room
implementation "android.arch.persistence.room:rxjava2:1.0.0"
// ReactiveStreams support for LiveData
implementation "android.arch.lifecycle:reactivestreams:1.0.0"
}
之前数据常常被保存在组件之中(例如在activity中创建的成员变量)
但是由于内存不足, 组件常常会遭到系统的清除, 这样会导致数据被清空(intent中的数据不会被清空), 就需要再次去请求服务器数据这样会导致体验不够流畅并且浪费流量.
所以组件不应该保存任何数据.
创建ViewModule
public class LiveDataTimerViewModel extends ViewModel {
/**/
}
绑定生命周期(或者说获取ViewModule的实例)
mLiveDataTimerViewModel = ViewModelProviders.of(this).get(LiveDataTimerViewModel.class);
其保存的数据和组件并不发生关系. 如果意外销毁后数据依旧是之前的数据不会重建(脱离于组件生命周期的数据)
并且在多个组件之间ViewModule的数据是可以共享的.
使用该类的静态方法来创建ViewModelProvider实例
static ViewModelProvider of(Fragment fragment) static ViewModelProvider of(FragmentActivity activity) static ViewModelProvider of(Fragment fragment, ViewModelProvider.Factory factory) static ViewModelProvider of(FragmentActivity activity, ViewModelProvider.Factory factory)
Factory可以用来创建你需要有参构造方法的ViewModule
<T extends ViewModel> T get(Class<T> modelClass)
<T extends ViewModel> T get(String key,
Class<T> modelClass)
继承这个类主要是可以拿到上下文Application.
查看源码:
public class AndroidViewModel extends ViewModel {
@SuppressLint("StaticFieldLeak")
private Application mApplication;
public AndroidViewModel(@NonNull Application application) {
mApplication = application;
}
/**
* Return the application.
*/
@NonNull
public <T extends Application> T getApplication() {
//noinspection unchecked
return (T) mApplication;
}
}
推荐使用 DefaultFactory 来创建他
ViewModelProviders.of(this, new ViewModelProviders.DefaultFactory(getApplication())).get(MyViewModule.class);
使数据变成一个可被观察状态, 并且符合视图的生命周期.
在活跃状态观察者可以接受到事件, 不活跃状态观察者不会接收到事件. 如果生命周期所有者被破坏自动删除观察者.
IllegalArgumentException
全部方法
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)
// 删除生命周期
这是一个抽象类, 我们一般都是用他的子类 MutableLiveData<T>
在ViewModel中创建liveData字段
一般情况下在ViewModel中创建字段, 但是也可以在任何模块下使用来解耦.
private MutableLiveData<Long> mElapsedTime = new MutableLiveData<>();
在数据变化后调用方法设置值(根据所处线程不同而调用不同的方法)
mElapsedTime.setValue(newValue); // 主线程 mElapsedTime.postValue(newValue); // 后台线程
然后在 Lifecycle 中注册观察者
final Observer<Long> elapsedTimeObserver = new Observer<Long>() {
@Override
public void onChanged(@Nullable final Long aLong) {
// 在观察者中更新ui
String newText = ChronoActivity3.this.getResources().getString(
R.string.seconds, aLong);
}
};
// 拿到LiveData然后绑定观察者
mLiveDataTimerViewModel.getElapsedTime().observe(this, elapsedTimeObserver);
如果在添加观察者之前已经设置值, 同样会回调一次观察者.
这个继承liveData(abstract). 只是公开了了两个私有方法
以下为全部源码:
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来实现
public class MyLiveData extends LiveData<String> {
/**
* 活跃状态
*/
@Override protected void onActive() {
super.onActive();
}
/**
* 非活跃状态
*/
@Override protected void onInactive() {
super.onInactive();
}
}
要想触发这两个方法必须要绑定观察者.
其实实现 LifecycleObserver 也能够实现生命周期的回调. 但是LiveData可以设置观察者
Transformations 提供两个方法, 类似于RxJava的操作符.
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)
示例:
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方法需要返回一个LiveData. 这个LiveData就是最终的结果
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;
}
});
可以设置多个源(LiveData). 然后通过观察者来监听多个LiveData的变化
<S> void addSource(LiveData<S> source, Observer<S> onChanged) // 添加源 <S> void removeSource(LiveData<S> toRemote) // 删除源
查看Transformation的源码也可以看到实际上就是运用MediatorLiveData.
@MainThread
public static <X, Y> LiveData<Y> map(@NonNull LiveData<X> source,
@NonNull final Function<X, Y> func) {
final MediatorLiveData<Y> result = new MediatorLiveData<>();
result.addSource(source, new Observer<X>() {
@Override
public void onChanged(@Nullable X x) {
result.setValue(func.apply(x));
}
});
return result;
}
生命周期组件, 可以将一个类赋予生命周期.
SupportLibrary的组件中都已经实现了 LifecycleOwer (例如 AppCompatActivity ), 所以我们可以在activity当中直接使用Lifecycle方法.
需要绑定生命周期的类实现接口 LifecycleObserver
public class MyLifecycle implements LifecycleObserver {}
将当前类作为观察者传入(lifecycleOwner一般由构造方法传入)
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 {
private LifecycleRegistry mLifecycleRegistry;
@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 mLifecycleRegistry;
}
}
通过LifecycleOwer获取Lifecycle实例然后得到状态
getLifecycle().getCurrentState()
有五种状态
Lifecycle.State CREATED Lifecycle.State DESTROYED Lifecycle.State INITIALIZED . Lifecycle.State RESUMED Lifecycle.State STARTED
ON_CREATE , ON_START , ON_RESUME 比其依附Activityd的生命周期方法要晚回调. 但是 ON_PAUSE , ON_STOP , ON_DESTROY 则要早回调.
上面提到了用注解来控制生命周期, 但是这只在java7之前有用. 在java8之后需要导入一个新的依赖
这意味着在java8全面使用在android上时, 注解方法将被放弃.
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
}
}
只能有一个或者没有参数, 但是可以增加一个 LifecycleOwner 参数. 并且 ON_ANY 注解的方法可以增加第二个注解 Event . 该参数的作用只是判断当前所处的生命周期.
class TestObserver implements LifecycleObserver {
@OnLifecycleEvent(ON_CREATE)
void onCreated(LifecycleOwner source) {}
@OnLifecycleEvent(ON_ANY)
void onAny(LifecycleOwner source, Event event) {}
}