几个不错的网址:
App开发架构指南(谷歌官方文档译文)
google源码 mvvm
感知生命周期的数据 – LiveData
App体系结构指南
https://github.com/BodhiSun/JetpackTestDemo
https://github.com/vi8er/MVVMFrame
MediatorLiveData#addSource之Android Architecture Components踩坑记录
Android LiveData 使用详解
Android之MVVM架构指南(四):LiveData
Android LiveData Transformations
安卓架构组件(4)-LiveData
Android Jetpack 架构组件最佳实践
LiveData使用解析并记录坑
LiveData 更新流程分析,小编在学习LiveData的时候有个疑问
@Override
protected void onResume() {
super.onResume();
MutableLiveData<String> mutableLiveData = new MutableLiveData<>();
Log.i("test", "onActivityCreated: xxxxxxxxxxx");
mutableLiveData.observe(this, new Observer<String>() {
@Override
public void onChanged(String s) {
Log.e("test", "onChanged:"+s);
}
});
mutableLiveData.setValue("新值");
//
}
看如上代码,setValue在observe之后,onChanged方法可以触发,但是setValue写在observe之前的时候,仍然可以触发onChanged方法,如下
@Override
protected void onResume() {
super.onResume();
MutableLiveData<String> mutableLiveData = new MutableLiveData<>();
Log.i("test", "onActivityCreated: xxxxxxxxxxx");
mutableLiveData.setValue("新值");
mutableLiveData.observe(this, new Observer<String>() {
@Override
public void onChanged(String s) {
Log.e("test", "onChanged:"+s);
}
});
//
}
这就有点疑问了,先添加观察者,后setValue更新值可以触发onChanged方法这个没有疑问,但是先setValue,后添加观察者,还能触发onChanged 这个就很是不解,如果这样的话,onChanged方法的触发会不会和setValue没有关系呢(结果是如果setValue注释掉的话,只有添加观察者,onChanged方法是不会触发的),下面开始跟源码回答这3个问题:
1、先添加观察者 observe,后setValue,onChanged方法触发的流程
2、先setValue,后添加观察者observe,onChanged方法触发的流程
3、只添加观察者observe,没有触发onChanged方法的流程
说之前交给大家一个查看方法调用栈的方法,输出日志信息
Log.e("test", "onChanged:"+Log.getStackTraceString(new Throwable()));
注意:这里小编把这个观察和setValue放到了onResume方法中,因为此时Activity的状态是Resume状态,执行观察的流程不是太多,如果你放到onCreate中去看(界面显示是onResume),在流程相关的方法其他方法中打断点时会发现执行很多次(比如lifcycle相关的生命周期执行了create start resume 影响分析onChanged方法的调用流程)
先添加观察者 observe,后setValue,onChanged方法触发的流程
mutableLiveData.observe(this, new Observer<String>() {
@Override
public void onChanged(String s) {
Log.e("test", "onChanged:"+s);
//Log.e("test", "onChanged:"+Log.getStackTraceString(new Throwable()));
}
});
mutableLiveData.setValue("新值");
mObservers.putIfAbsent 方法会将观察者加入mObservers集合
@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
assertMainThread("observe");
if (owner.getLifecycle().getCurrentState() == DESTROYED) {
// ignore
return;
}
LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
if (existing != null && !existing.isAttachedTo(owner)) {
throw new IllegalArgumentException("Cannot add the same observer"
+ " with different lifecycles");
}
if (existing != null) {
return;
}
owner.getLifecycle().addObserver(wrapper);
}
看下liveData中setValue调用时
void dispatchingValue(@Nullable ObserverWrapper initiator) {
if (mDispatchingValue) {
mDispatchInvalidated = true;
return;
}
mDispatchingValue = true;
do {
mDispatchInvalidated = false;
if (initiator != null) {
considerNotify(initiator);//先setValue后观察,会执行这个方法
initiator = null;
} else {
for (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator =
mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
considerNotify(iterator.next().getValue());//先观察后setValue会执行这个方法
if (mDispatchInvalidated) {
break;
}
}
}
} while (mDispatchInvalidated);
mDispatchingValue = false;
}
只观察不调用setValue的时候为何没有触发onChanged方法,看下
首先跟setValue方法做了什么事情,首先是mVersion自加,dispatchingValue中的一些变量的设置,以及根据观察者做的处理
,这里没有调用setValue方法,所以onChanged方法没有触发,会不是因为mVersion的没有改变,或者dispatchingValue中的一些变量没有改变导致的onChanged方法没有触发呢?思考一下
@MainThread
protected void setValue(T value) {
assertMainThread("setValue");
mVersion++;
mData = value;
dispatchingValue(null);
}
livedata中的considerNotify
@SuppressWarnings("unchecked")
private void considerNotify(ObserverWrapper observer) {
if (!observer.mActive) {
return;
}
// Check latest state b4 dispatch. Maybe it changed state but we didn't get the event yet.
//
// we still first check observer.active to keep it as the entrance for events. So even if
// the observer moved to an active state, if we've not received that event, we better not
// notify for a more predictable notification order.
if (!observer.shouldBeActive()) {
observer.activeStateChanged(false);
return;
}
if (observer.mLastVersion >= mVersion) {
return;
}//不调用setValue方法时,这个地放直接执行了return方法,所以下面的onChanged方法的回调不会执行了
observer.mLastVersion = mVersion;
observer.mObserver.onChanged((T) mData);
}
看下onChanged方法的调用栈,流程就很清楚了(先setValue,后观察的调用栈信息)
2020-09-22 22:40:46.343 32726-32726/com.tt.test E/test: onChanged:java.lang.Throwable
at com.tt.test.aac.AACActivity$1.onChanged(AACActivity.java:36)
at com.tt.test.aac.AACActivity$1.onChanged(AACActivity.java:32)
at androidx.lifecycle.LiveData.considerNotify(LiveData.java:133)
at androidx.lifecycle.LiveData.dispatchingValue(LiveData.java:146)
at androidx.lifecycle.LiveData$ObserverWrapper.activeStateChanged(LiveData.java:468)
at androidx.lifecycle.LiveData$LifecycleBoundObserver.onStateChanged(LiveData.java:425)
at androidx.lifecycle.LifecycleRegistry$ObserverWithState.dispatchEvent(LifecycleRegistry.java:354)
at androidx.lifecycle.LifecycleRegistry.addObserver(LifecycleRegistry.java:196)
at androidx.lifecycle.LiveData.observe(LiveData.java:205)
at com.tt.test.aac.AACActivity.onResume(AACActivity.java:32)
有不清楚的可以留言
如何想看只写观察者的流程,可以在observe上加断点,查看。之所以Activity或者Fragment生命周期改变时,会执行observe方法相关的方法,是因为Activity或Fragment生命周期改变时会调用
handleLifecycleEvent
方法,以Activity onDestroy方法为例
最终在FragmentActivity方法中会有如下调用
/**
* Destroy all fragments.
*/
@Override
protected void onDestroy() {
super.onDestroy();
mFragments.dispatchDestroy();
mFragmentLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY);
}
AACActivity extends AppCompatActivity
AppCompatActivity extends FragmentActivity
判断应用是否在前台
之前的写法:
registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
}
@Override
public void onActivityStarted(Activity activity) {
}
@Override
public void onActivityResumed(Activity activity) {
}
@Override
public void onActivityPaused(Activity activity) {
}
@Override
public void onActivityStopped(Activity activity) {
}
@Override
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
}
@Override
public void onActivityDestroyed(Activity activity) {
}
});
现在的写法:
使用google Lifecycle判断应用在前台还是后台的方法(小编把lifecycle相关的依赖都写上了,如下)
def lifecycle_version = "2.3.0-alpha07"
def arch_version = "2.1.0"
// ViewModel
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version"
// LiveData
implementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version"
// Lifecycles only (without ViewModel or LiveData)
implementation "androidx.lifecycle:lifecycle-runtime-ktx:$lifecycle_version"
// Saved state module for ViewModel
implementation "androidx.lifecycle:lifecycle-viewmodel-savedstate:$lifecycle_version"
// Annotation processor
kapt "androidx.lifecycle:lifecycle-compiler:$lifecycle_version"
// alternately - if using Java8, use the following instead of lifecycle-compiler
implementation "androidx.lifecycle:lifecycle-common-java8:$lifecycle_version"
// optional - helpers for implementing LifecycleOwner in a Service
implementation "androidx.lifecycle:lifecycle-service:$lifecycle_version"
// optional - ProcessLifecycleOwner provides a lifecycle for the whole application process
implementation "androidx.lifecycle:lifecycle-process:$lifecycle_version"
// optional - ReactiveStreams support for LiveData
implementation "androidx.lifecycle:lifecycle-reactivestreams-ktx:$lifecycle_version"
// optional - Test helpers for LiveData
testImplementation "androidx.arch.core:core-testing:$arch_version"
首先定义一个实现了LifecyclerObserver接口的类:
public class LifecyclerChecker implements LifecycleObserver
然后在这个类中加入如下代码:
@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
public void onAppBackground() {
// 应用进入后台
Log.e("test","LifecycleChecker onAppBackground ON_STOP");
}
@OnLifecycleEvent(Lifecycle.Event.ON_START)
public void onAppForeground() {
// 应用进入前台
Log.e("test","LifecycleChecker onAppForeground ON_START");
}
上面的方法名是随便起的,重要的是注解
@OnLifecycleEvent(Lifecycle.Event.ON_STOP) 表示应用进入后台
@OnLifecycleEvent(Lifecycle.Event.ON_START)表示应用进入前台
最后,在合适的地方调用下面的方法:
ProcessLifecycleOwner.get().getLifecycle().addObserver(new LifecycleChecker()); //可以选择在自定义的Application的onCreate中调用
下面这个方法无论是在Application的onCreate中调用,还是在Activity的onCreate或者其他的生命周期函数中调用都可以,你可以在自己喜欢的地方调用。
ProcessLifecycleOwner判断Android应用程序前后台切换
android livedata组件学习
视频录制
日历收集项目
如何配置Tigase的SSL/TLS证书?
nio和netty
2020年9月17 23:30 ylxy3