架构库
-
LiveData
数据变更观察者, 我觉得和DataBinding的Observable接口发生冲突
-
ViewModel
解耦数据脱离组件, 防止意外销毁
-
Lifecyle
分离生命周期
-
Room
(推荐使用Realm替代, Reaml+RxJava可以替代Room+LiveData, 并且更加强大)
-
DataBinding
数据和Ui的双向绑定, 数据变更观察者
参考文献
Demo
android-lifecycles : 关于lifecycle/viewModule/liveData的示例
android-architecture-components
- LiveData在某些情况下可使用RxJava2代替。
- Lifecyle等生命周期管理我们可以借助RxLifeCyle。
- 数据层官方推荐使用Room或者Realm,等其他ORM皆可。
- 网络请求库推荐使用
Retrofit+Okhttp
- 多层之间解耦合,推荐使用服务发现(Service Locator) 或者依赖注入(DI),推荐
Dagger2
。 - Modle和View绑定我们可以使用DataBinding进行快速实现
- 在使用组件架构时候,推荐使用MvpClean,切记不要Mvp,Mvp,Mvp!
导入依赖
完整依赖
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"
}
复制代码
ViewModule
之前数据常常被保存在组件之中(例如在activity中创建的成员变量)
但是由于内存不足, 组件常常会遭到系统的清除, 这样会导致数据被清空(intent中的数据不会被清空), 就需要再次去请求服务器数据这样会导致体验不够流畅并且浪费流量.
所以组件不应该保存任何数据.
创建ViewModule
public class LiveDataTimerViewModel extends ViewModel {
/**/
}
复制代码
绑定生命周期(或者说获取ViewModule的实例)
mLiveDataTimerViewModel = ViewModelProviders.of(this).get(LiveDataTimerViewModel.class);
复制代码
其保存的数据和组件并不发生关系. 如果意外销毁后数据依旧是之前的数据不会重建(脱离于组件生命周期的数据)
并且在多个组件之间ViewModule的数据是可以共享的.
ViewModelProviders
使用该类的静态方法来创建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
ViewModelProvider
<T extends ViewModel> T get(Class<T> modelClass)
<T extends ViewModel> T get(String key,
Class<T> modelClass)
复制代码
AndroidViewModel
继承这个类主要是可以拿到上下文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);
复制代码
LiveData
使数据变成一个可被观察状态, 并且符合视图的生命周期.
在活跃状态观察者可以接受到事件, 不活跃状态观察者不会接收到事件. 如果生命周期所有者被破坏自动删除观察者.
- 添加已被销毁的生命周期所有者, 会忽略
- 添加已经被添加过的生命周期所有者也会忽略
- 如果观察者已经被另一个liveData添加过, 会抛出
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);
复制代码
如果在添加观察者之前已经设置值, 同样会回调一次观察者.
MutableLiveData
这个继承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
可以通过继承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;
}
});
复制代码
MediatorLiveData
可以设置多个源(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;
}
复制代码
Lifecycle
生命周期组件, 可以将一个类赋予生命周期.
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) {}
}
复制代码
Room
包含在ArchitectureComponent
组件中的数据库框架, 最终还是SQL语句配合接口抽象方法来实现数据库操作, 可以配合LiveData
监听数据库事件(数据库查询结果返回LiveData
);
我还是更加喜欢Realm这种NOSQL的高性能和方便.
注解
@Query
@Insert
@Delete
@Update