LifeCycle
Lifecycles提供了一种通过观察者模式来监听Activity和Fragment的生命周期变化的方式。之前,我们解决这种需求的方法是在Activity和Fragment的生命周期方法 onXX 系列方法中直接嵌入功能代码或调用回调,现在通过Lifecycles来实现监听可以有效减少耦合,隔离功能代码。
Lifecycles框架中包括三个角色: Lifecycle、LifecycleOwner、LifecycleObserver,其中Lifecycle包含有关组件(例如Activity或Fragment)生命周期状态的信息,并允许其他对象观察此状态;LifecycleOwner表示一个拥有Lifecycle的类,LifecycleObserver则是LifecycleOwner的生命周期状态的监听者。
LifeCycle提供如下能力:
1.Android生命周期 事件的监听
2.Android生命周期 状态的获取
所以定义了如下枚举类型
当Activity/Fragment 执行对应的生命周期方法之后,都会触发相应的事件
public enum Event {
ON_CREATE,
ON_START,
ON_RESUME,
ON_PAUSE,
ON_STOP,
ON_DESTROY,
ON_ANY
}
Activity/Fragment 在当前生命周期下,对应的LifeCycle state
public enum State {
DESTROYED,
INITIALIZED,
CREATED,
STARTED,
RESUMED;
public boolean isAtLeast(@NonNull State state) {
return compareTo(state) >= 0;
}
}
LifecycleOwner
LifecycleOwner 标记了谁具有Lifecycle对象,ComponentActivity , Fragment 都实现了该接口
public interface LifecycleOwner {
@NonNull
Lifecycle getLifecycle();
}
LifecycleEventObserver
public interface LifecycleEventObserver extends LifecycleObserver {
void onStateChanged(LifecycleOwner source, Lifecycle.Event event);
}
interface FullLifecycleObserver extends LifecycleObserver {
void onCreate(LifecycleOwner owner);
void onStart(LifecycleOwner owner);
void onResume(LifecycleOwner owner);
void onPause(LifecycleOwner owner);
void onStop(LifecycleOwner owner);
void onDestroy(LifecycleOwner owner);
}
public interface DefaultLifecycleObserver extends FullLifecycleObserver {
default void onCreate(LifecycleOwner owner) { }
default void onStart(LifecycleOwner owner) { }
default void onResume(LifecycleOwner owner) { }
default void onPause( LifecycleOwner owner) { }
default void onStop(LifecycleOwner owner) { }
default void onDestroy(LifecycleOwner owner) { }
}
ComponentActivity 和 Fragment 都实现了LifecycleOwner接口,那么具体的周期事件分发时,并不是直接写在具体的生命周期方法内呢? 而是放在了ReportFragment里
ComponentActivity
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mSavedStateRegistryController.performRestore(savedInstanceState);
ReportFragment.injectIfNeededIn(this);
if (mContentLayoutId != 0) {
setContentView(mContentLayoutId);
}
}
ReportFragment
public class ReportFragment extends Fragment {
public static void injectIfNeededIn(Activity activity) {
// ProcessLifecycleOwner should always correctly work and some activities may not extend
// FragmentActivity from support lib,so we use framework fragments for activities
if (Build.VERSION.SDK_INT >= 29) {
// On API 29+, we can register for the correct Lifecycle callbacks directly
activity.registerActivityLifecycleCallbacks(new LifecycleCallbacks());
}
android.app.FragmentManager manager = activity.getFragmentManager();
if (manager.findFragmentByTag(REPORT_FRAGMENT_TAG) == null) {
manager.beginTransaction().add(new ReportFragment(), REPORT_FRAGMENT_TAG).commit();
// Hopefully,we are the first to make a transaction.
manager.executePendingTransactions();
}
}
}
那么如果我们的Activity 没有继承自ComponentActivity,那么有什么办法向每个Activity 里加入ReportFragment呢?
借助Application.registerActivityLifecycleCallbacks 方法,在onActivityCreated 方法注入这个ReportFragment
ProcessLifecycleOwnerInitializer (lifecycle-process 2.2.0)
public class ProcessLifecycleOwnerInitializer extends ContentProvider {
@Override
public boolean onCreate() {
LifecycleDispatcher.init(getContext());
ProcessLifecycleOwner.init(getContext());
return true;
}
}
LifecycleDispatcher (lifecycle-process 2.2.0)
class LifecycleDispatcher {
static void init(Context context) {
((Application) context.getApplicationContext())
.registerActivityLifecycleCallbacks(new DispatcherActivityCallback());
}
static class DispatcherActivityCallback extends EmptyActivityLifecycleCallbacks {
@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
ReportFragment.injectIfNeededIn(activity);
}
}
}
ReportFragment (lifecycle-runtime 2.1.0)
public class ReportFragment extends Fragment {
// 尝试获取 Activity 中的 LifecycleRegistry 并调用 handleLifecycleEvent
private void dispatch(Lifecycle.Event event) {
Activity activity = getActivity();
if (activity instanceof LifecycleRegistryOwner) {
((LifecycleRegistryOwner) activity).getLifecycle().handleLifecycleEvent(event);
return;
}
if (activity instanceof LifecycleOwner) {
Lifecycle lifecycle = ((LifecycleOwner) activity).getLifecycle();
if (lifecycle instanceof LifecycleRegistry) {
((LifecycleRegistry) lifecycle).handleLifecycleEvent(event);
}
}
}
Api<=28
// 各个生命周期钩子中,调用 dispatch
@Override
public void onStart() {
super.onStart();
dispatch(Lifecycle.Event.ON_START);
}
Api>28
static class LifecycleCallbacks implements Application.ActivityLifecycleCallbacks {
// ActivityLifecycleCallbacks的各个生命周期钩子中,调用 dispatch
@Override
public void onActivityPostCreated(@NonNull Activity activity,
@Nullable Bundle savedInstanceState) {
dispatch(activity, Lifecycle.Event.ON_CREATE);
}
......
}
// 2.1.0 及之前版本调用的方法
private void dispatch(@NonNull Lifecycle.Event event) {
if (Build.VERSION.SDK_INT < 29) {
// Only dispatch events from ReportFragment on API levels prior
// to API 29. On API 29+, this is handled by the ActivityLifecycleCallbacks
// added in ReportFragment.injectIfNeededIn
dispatch(getActivity(), event);
}
}
// 2.2.0 新增的 dispatch 重载
static void dispatch(@NonNull Activity activity, @NonNull Lifecycle.Event event) {
if (activity instanceof LifecycleRegistryOwner) {
((LifecycleRegistryOwner) activity).getLifecycle().handleLifecycleEvent(event);
return;
}
if (activity instanceof LifecycleOwner) {
Lifecycle lifecycle = ((LifecycleOwner) activity).getLifecycle();
if (lifecycle instanceof LifecycleRegistry) {
((LifecycleRegistry) lifecycle).handleLifecycleEvent(event);
}
}
}
}
LifecycleRegistry
/**
* Custom list that keeps observers and can handle removals / additions during traversal.
*
* Invariant: at any moment of time for observer1 & observer2:
* if addition_order(observer1) < addition_order(observer2), then
* state(observer1) >= state(observer2),
*/
维护了状态有序性,即后加入的observer的state一定不大于先加入的observer的state
private FastSafeIterableMap<LifecycleObserver, ObserverWithState> mObserverMap =
new FastSafeIterableMap<>();
/**
* Current state
*/
private State mState;
/**
* The provider that owns this Lifecycle.
* Only WeakReference on LifecycleOwner is kept, so if somebody leaks Lifecycle, they won't leak
* the whole Fragment / Activity. However, to leak Lifecycle object isn't great idea neither,
* because it keeps strong references on all other listeners, so you'll leak all of them as
* well.
*/
private final WeakReference<LifecycleOwner> mLifecycleOwner;
private int mAddingObserverCounter = 0;
private boolean mHandlingEvent = false;
private boolean mNewEventOccurred = false;
public LifecycleRegistry(@NonNull LifecycleOwner provider) {
mLifecycleOwner = new WeakReference<>(provider);
mState = INITIALIZED;
}
// we have to keep it for cases:
// void onStart() {
// mRegistry.removeObserver(this);
// mRegistry.add(newObserver);
// }
// newObserver should be brought only to CREATED state during the execution of
// this onStart method. our invariant with mObserverMap doesn't help, because parent observer
// is no longer in the map.
private ArrayList<State> mParentStates = new ArrayList<>();
@Override
public void addObserver(@NonNull LifecycleObserver observer) {
//1
State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
//2
ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);
if (previous != null) {
return;
}
LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
if (lifecycleOwner == null) {
return;
}
//3 先判断是否是在sync过程中新add的observer
boolean isReentrance = mAddingObserverCounter != 0 || mHandlingEvent;
// 计算当前observer应该最终到达什么状态
State targetState = calculateTargetState(observer);
mAddingObserverCounter++;
while ((statefulObserver.mState.compareTo(targetState) < 0
&& mObserverMap.contains(observer))) {
// we have to keep it for cases:
// void onStart() {
// mRegistry.removeObserver(this);
// mRegistry.add(newObserver);
// }
// newObserver should be brought only to CREATED state during the execution of
// this onStart method. our invariant with mObserverMap doesn't help, because parent observer
// is no longer in the map.
pushParentState(statefulObserver.mState);
statefulObserver.dispatchEvent(lifecycleOwner, upEvent(statefulObserver.mState));
popParentState();
targetState = calculateTargetState(observer);
}
if (!isReentrance) {
sync();
}
mAddingObserverCounter--;
}
static class ObserverWithState {
State mState;
LifecycleEventObserver mLifecycleObserver;
ObserverWithState(LifecycleObserver observer, State initialState) {
mLifecycleObserver = Lifecycling.lifecycleEventObserver(observer);
mState = initialState;
}
void dispatchEvent(LifecycleOwner owner, Event event) {
State newState = getStateAfter(event);
mState = min(mState, newState);
mLifecycleObserver.onStateChanged(owner, event);
mState = newState;
}
}
private static Event downEvent(State state) {
switch (state) {
case INITIALIZED:
throw new IllegalArgumentException();
case CREATED:
return ON_DESTROY;
case STARTED:
return ON_STOP;
case RESUMED:
return ON_PAUSE;
case DESTROYED:
throw new IllegalArgumentException();
}
throw new IllegalArgumentException("Unexpected state value " + state);
}
private static Event upEvent(State state) {
switch (state) {
case INITIALIZED:
case DESTROYED:
return ON_CREATE;
case CREATED:
return ON_START;
case STARTED:
return ON_RESUME;
case RESUMED:
throw new IllegalArgumentException();
}
throw new IllegalArgumentException("Unexpected state value " + state);
}
如果我们外部传入的是DefaultLifecycleObserver, 则会被转换为下面的对象
class FullLifecycleObserverAdapter implements LifecycleEventObserver {
private final FullLifecycleObserver mFullLifecycleObserver;
private final LifecycleEventObserver mLifecycleEventObserver;
FullLifecycleObserverAdapter(FullLifecycleObserver fullLifecycleObserver,
LifecycleEventObserver lifecycleEventObserver) {
mFullLifecycleObserver = fullLifecycleObserver;
mLifecycleEventObserver = lifecycleEventObserver;
}
@Override
public void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event) {
switch (event) {
case ON_CREATE:
mFullLifecycleObserver.onCreate(source);
break;
case ON_START:
mFullLifecycleObserver.onStart(source);
break;
case ON_RESUME:
mFullLifecycleObserver.onResume(source);
break;
case ON_PAUSE:
mFullLifecycleObserver.onPause(source);
break;
case ON_STOP:
mFullLifecycleObserver.onStop(source);
break;
case ON_DESTROY:
mFullLifecycleObserver.onDestroy(source);
break;
case ON_ANY:
throw new IllegalArgumentException("ON_ANY must not been send by anybody");
}
if (mLifecycleEventObserver != null) {
mLifecycleEventObserver.onStateChanged(source, event);
}
}
}
public void handleLifecycleEvent(@NonNull Lifecycle.Event event) {
State next = getStateAfter(event);
moveToState(next);
}
private void moveToState(State next) {
if (mState == next) {
return;
}
mState = next;
if (mHandlingEvent || mAddingObserverCounter != 0) {
mNewEventOccurred = true;
// we will figure out what to do on upper level.
return;
}
mHandlingEvent = true;
sync();
mHandlingEvent = false;
}
private void sync() {
LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
if (lifecycleOwner == null) {
throw new IllegalStateException("LifecycleOwner of this LifecycleRegistry is already"
+ "garbage collected. It is too late to change lifecycle state.");
}
while (!isSynced()) {
mNewEventOccurred = false;
// 如果newState比最后一个observer 的state 都小,即降级,则从后向前遍历
if (mState.compareTo(mObserverMap.eldest().getValue().mState) < 0) {
backwardPass(lifecycleOwner);
}
// 如果newState比第一个observer的状态大,即升级,则从前向后遍历,都是为了维护observers的状态有序性
Entry<LifecycleObserver, ObserverWithState> newest = mObserverMap.newest();
if (!mNewEventOccurred && newest != null
&& mState.compareTo(newest.getValue().mState) > 0) {
forwardPass(lifecycleOwner);
}
}
mNewEventOccurred = false;
}
LiveData
LiveData 就像是一个去除了所有操作符的Rxjava , 一个简单的响应式框架。
LiveData主要声明了注册和反注册的接口,注册有两种方式,一是使用observe方法,这个方法需要LifecycleOwner参数,这个方法注册的订阅者,只有在owner的生命状态处于STARTED或者RESUMED状态的时候才会收到数据改变的回调,同时,会在接到onDestory 事件时自动unRegister自己,防止内存泄漏。 还有一种注册方式是observeForever方法,这种方式注册的订阅者就是一直生效的,所以可能会造成内存泄漏,需要及时调用removeObserver方法解注册,相对应的,还有removeObservers方法解注册这个LifecycleOwner的所有订阅者。
public abstract class LiveData<T> {
@SuppressWarnings("WeakerAccess") /* synthetic access */
final Object mDataLock = new Object();
static final int START_VERSION = -1;
@SuppressWarnings("WeakerAccess") /* synthetic access */
static final Object NOT_SET = new Object();
private SafeIterableMap<Observer<? super T>, ObserverWrapper> mObservers =
new SafeIterableMap<>();
// how many observers are in active state
@SuppressWarnings("WeakerAccess") /* synthetic access */
int mActiveCount = 0;
private volatile Object mData;
// when setData is called, we set the pending data and actual data swap happens on the main
// thread
@SuppressWarnings("WeakerAccess") /* synthetic access */
volatile Object mPendingData = NOT_SET;
private int mVersion;
private boolean mDispatchingValue;
@SuppressWarnings("FieldCanBeLocal")
private boolean mDispatchInvalidated;
private final Runnable mPostValueRunnable = new Runnable() {
@SuppressWarnings("unchecked")
@Override
public void run() {
Object newValue;
synchronized (mDataLock) {
newValue = mPendingData;
mPendingData = NOT_SET;
}
setValue((T) newValue);
}
};
/**
* Creates a LiveData initialized with the given {@code value}.
*
* @param value initial value
*/
public LiveData(T value) {
mData = value;
mVersion = START_VERSION + 1;
}
/**
* Creates a LiveData with no value assigned to it.
*/
public LiveData() {
mData = NOT_SET;
mVersion = START_VERSION;
}
注册observer
@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);
}
class LifecycleBoundObserver extends ObserverWrapper implements LifecycleEventObserver {
@NonNull
final LifecycleOwner mOwner;
LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer<? super T> observer) {
super(observer);
mOwner = owner;
}
@Override
boolean shouldBeActive() {
return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
}
@Override
public void onStateChanged(@NonNull LifecycleOwner source,
@NonNull Lifecycle.Event event) {
if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
removeObserver(mObserver);
return;
}
activeStateChanged(shouldBeActive());
}
}
private abstract class ObserverWrapper {
void activeStateChanged(boolean newActive) {
if (newActive == mActive) {
return;
}
// immediately set active state, so we'd never dispatch anything to inactive
// owner
mActive = newActive;
//...
if (mActive) {
dispatchingValue(this);
}
}
}
mDispatchingValue & mdispatchinvalidated 还是为了处理嵌套问题,如果在遍历处理observer时,再一次setValue ,那么保证重新来一遍循环遍历就可以了
void dispatchingValue(@Nullable ObserverWrapper initiator) {
if (mDispatchingValue) {
mDispatchInvalidated = true;
return;
}
mDispatchingValue = true;
do {
mDispatchInvalidated = false;
if (initiator != null) {
considerNotify(initiator);
initiator = null;
} else {
for (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator =
mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
considerNotify(iterator.next().getValue());
if (mDispatchInvalidated) {
break;
}
}
}
} while (mDispatchInvalidated);
mDispatchingValue = false;
}
private void considerNotify(ObserverWrapper observer) {
if (!observer.mActive) {
return;
}
if (!observer.shouldBeActive()) {
observer.activeStateChanged(false);
return;
}
if (observer.mLastVersion >= mVersion) {
return;
}
observer.mLastVersion = mVersion;
observer.mObserver.onChanged((T) mData);
}
setValue & postValue
postValue 对dataLock 加了锁,通过mPendingData 是否等于 NOT_SET来判断是否有值已经赋给了mPendingData,但还没有同步到newValue(即有一个mPostValueRunnable在队列中还未执行),进而决定是不是还需要调用mPostValueRunnable。这种做法造成的后果是当postValue同时调用多次时,mPostValueRunnable只调用一次,mPendingData的值会等于最后一个获取到锁的线程设置的值,即其他线程设置的值都会丢失。这个是使用时要注意的
//
protected void postValue(T value) {
boolean postTask;
synchronized (mDataLock) {
postTask = mPendingData == NOT_SET;
mPendingData = value;
}
if (!postTask) {
return;
}
ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
}
/**
* Sets the value. If there are active observers, the value will be dispatched to them.
* <p>
* This method must be called from the main thread. If you need set a value from a background
* thread, you can use {@link #postValue(Object)}
*
* @param value The new value
*/
@MainThread
protected void setValue(T value) {
assertMainThread("setValue");
mVersion++;
mData = value;
dispatchingValue(null);
}
MediatorLiveData
/**
* Starts to listen the given {@code source} LiveData, {@code onChanged} observer will be called
* when {@code source} value was changed.
* <p>
* {@code onChanged} callback will be called only when this {@code MediatorLiveData} is active.
* <p> If the given LiveData is already added as a source but with a different Observer,
* {@link IllegalArgumentException} will be thrown.
*
* @param source the {@code LiveData} to listen to
* @param onChanged The observer that will receive the events
* @param <S> The type of data hold by {@code source} LiveData
*/
@MainThread
public <S> void addSource(@NonNull LiveData<S> source, @NonNull Observer<? super S> onChanged) {
Source<S> e = new Source<>(source, onChanged);
Source<?> existing = mSources.putIfAbsent(source, e);
if (existing != null && existing.mObserver != onChanged) {
throw new IllegalArgumentException(
"This source was already added with the different observer");
}
if (existing != null) {
return;
}
if (hasActiveObservers()) {
e.plug();
}
}
private static class Source<V> implements Observer<V> {
final LiveData<V> mLiveData;
final Observer<? super V> mObserver;
int mVersion = START_VERSION;
Source(LiveData<V> liveData, final Observer<? super V> observer) {
mLiveData = liveData;
mObserver = observer;
}
void plug() {
mLiveData.observeForever(this);
}
void unplug() {
mLiveData.removeObserver(this);
}
@Override
public void onChanged(@Nullable V v) {
if (mVersion != mLiveData.getVersion()) {
mVersion = mLiveData.getVersion();
mObserver.onChanged(v);
}
}
}
@CallSuper
@Override
protected void onActive() {
for (Map.Entry<LiveData<?>, Source<?>> source : mSources) {
source.getValue().plug();
}
}
@CallSuper
@Override
protected void onInactive() {
for (Map.Entry<LiveData<?>, Source<?>> source : mSources) {
source.getValue().unplug();
}
}
MediatorLiveData 能做些什么呢?
public class Transformations {
@MainThread
public static <X> LiveData<X> distinctUntilChanged(LiveData<X> source)
@MainThread
public static <X, Y> LiveData<Y> map(LiveData<X> source,final Function<X, Y> mapFunction)
@MainThread
public static <X, Y> LiveData<Y> switchMap( LiveData<X> source,final Function<X, LiveData<Y>> switchMapFunction)
}
@MainThread
public static <X, Y> LiveData<Y> map(
@NonNull LiveData<X> source,
@NonNull final Function<X, Y> mapFunction) {
final MediatorLiveData<Y> result = new MediatorLiveData<>();
result.addSource(source, new Observer<X>() {
@Override
public void onChanged(@Nullable X x) {
result.setValue(mapFunction.apply(x));
}
});
return result;
}
@MainThread
public static <X, Y> LiveData<Y> switchMap(
@NonNull LiveData<X> source,
@NonNull final Function<X, LiveData<Y>> switchMapFunction) {
final MediatorLiveData<Y> result = new MediatorLiveData<>();
result.addSource(source, new Observer<X>() {
LiveData<Y> mSource;
@Override
public void onChanged(@Nullable X x) {
LiveData<Y> newLiveData = switchMapFunction.apply(x);
if (mSource == newLiveData) {
return;
}
if (mSource != null) {
result.removeSource(mSource);
}
mSource = newLiveData;
if (mSource != null) {
result.addSource(mSource, new Observer<Y>() {
@Override
public void onChanged(@Nullable Y y) {
result.setValue(y);
}
});
}
}
});
return result;
}
interface fun<X, Y> {
Y apply(X o);
}
static <X, Y> MutableLiveData<Y> map(LiveData<X> data, final fun<X, Y> f) {
final MutableLiveData<Y> r = new MutableLiveData<Y>();
data.observeForever(new Observer<X>() {
@Override
public void onChanged(X o) {
Y s = f.apply(o);
r.setValue(s);
}
});
return r;
}
LiveDataBus 简单实现(美团)
public final class LiveDataBus {
private final Map<String, MutableLiveData<Object>> bus;
private LiveDataBus() {
bus = new HashMap<>();
}
private static class SingletonHolder {
private static final LiveDataBus DATA_BUS = new LiveDataBus();
}
public static LiveDataBus get() {
return SingletonHolder.DATA_BUS;
}
public <T> MutableLiveData<T> getChannel(String target, Class<T> type) {
if (!bus.containsKey(target)) {
bus.put(target, new MutableLiveData<>());
}
return (MutableLiveData<T>) bus.get(target);
}
public MutableLiveData<Object> getChannel(String target) {
return getChannel(target, Object.class);
}
}
自己简单写了一个
public class LiveDataBus {
static LiveDataBus INSTANCE = new LiveDataBus();
MutableLiveData<Object> mLiveData = new MutableLiveData<Object>();
public static LiveDataBus getDefault() {
return INSTANCE;
}
public void postEvent(Object o) {
mLiveData.setValue(o);
}
public <T> LiveData<T> ofType(final Class<T> c) {
final MediatorLiveData<T> liveData = new MediatorLiveData<T>();
mLiveData.observeForever(new Observer<Object>() {
@Override
public void onChanged(Object o) {
if (c.isInstance(o)) {
liveData.setValue((T) o);
}
}
});
return liveData;
}
}
ViewModel
提起ViewModel ,第一想到的可能是MVVM, 即数据驱动视图的思想。
Google 官方的ViewModel 的根本职责,就是负责维护UI的状态,追根究底就是维护对应的数据。它为我们提供了两个功能
1、配置更改期间自动保留其数据 (比如屏幕的横竖旋转)
2、Activity、Fragment等UI组件之间的通信(数据共享)
首先看第一点,如何保证我们的ViewModel 能够在由于配置更改导致的Activity 重建时,还能为我们保留数据。
1、onSavedInstanceState
2、Fragment 的 setRetainInstance 方法
3、NonConfigurationInstances
存储数据,就用LiveData 去存就可以
对于第二点,Fragment 共享数据,那其实意思就是在同一个作用域下,fragment 通过使用Activity的ViewModelStore 获取到同一个ViewModel。保证ViewModel 在一个作用域只有一个唯一实例, 但可能有多个不同作用类型的ViewModel 对象,所以需要一个Map 将其存起来一一对应。 调用统一的get 方法,如果存在则返回实例,否则就New一个返回,并存在map 里,以便下次获取。
Activity 里如何获取ViewModel
ViewModelProviders.of(this).get(ZtGamePhotoListPageViewModel.class)
new ViewModelProvider(getViewModelStore(), new ViewModelProvider.NewInstanceFactory())
.get(MyViewModel.class)
MyViewModel viewModel = new ViewModelProvider(this, new ViewModelProvider.Factory() {
@NonNull
@Override
public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
return (T) new MyViewModel();
}
}).get(MyViewModel.class);
//ComponentActivity getViewModelStore
@NonNull
@Override
public ViewModelStore getViewModelStore() {
if (getApplication() == null) {
throw new IllegalStateException("Your activity is not yet attached to the "
+ "Application instance. You can't request ViewModel before onCreate call.");
}
if (mViewModelStore == null) {
NonConfigurationInstances nc =
(NonConfigurationInstances) getLastNonConfigurationInstance();
if (nc != null) {
// Restore the ViewModelStore from NonConfigurationInstances
mViewModelStore = nc.viewModelStore;
}
if (mViewModelStore == null) {
mViewModelStore = new ViewModelStore();
}
}
return mViewModelStore;
}
// Fragment getgetViewModelStore
@NonNull
@Override
public ViewModelStore getViewModelStore() {
if (mFragmentManager == null) {
throw new IllegalStateException("Can't access ViewModels from detached fragment");
}
return mFragmentManager.getViewModelStore(this);
}
// mNonConfig FragmentManagerViewModel
@NonNull
ViewModelStore getViewModelStore(@NonNull Fragment f) {
return mNonConfig.getViewModelStore(f);
}
@NonNull
ViewModelStore getViewModelStore(@NonNull Fragment f) {
ViewModelStore viewModelStore = mViewModelStores.get(f.mWho);
if (viewModelStore == null) {
viewModelStore = new ViewModelStore();
mViewModelStores.put(f.mWho, viewModelStore);
}
return viewModelStore;
}
FragmentManagerViewModel 是在fragment Attach 时创建出来的
void performAttach() {
mChildFragmentManager.attachController(mHost, new FragmentContainer())
...
}
public void attachController(@NonNull FragmentHostCallback host,
@NonNull FragmentContainer container, @Nullable final Fragment parent) {
// Get the FragmentManagerViewModel
if (parent != null) {
mNonConfig = parent.mFragmentManager.getChildNonConfig(parent);
} else if (host instanceof ViewModelStoreOwner) {
ViewModelStore viewModelStore = ((ViewModelStoreOwner) host).getViewModelStore();
mNonConfig = FragmentManagerViewModel.getInstance(viewModelStore);
} else {
mNonConfig = new FragmentManagerViewModel(false);
}
}
内存不足导致Activity 非正常销毁情况下,ViewModel 的数据保存
SavedStateRegistryController,SavedStateRegistryOwner,SavedStateRegistry
@CallSuper
@Override
protected void onSaveInstanceState(@NonNull Bundle outState) {
Lifecycle lifecycle = getLifecycle();
if (lifecycle instanceof LifecycleRegistry) {
((LifecycleRegistry) lifecycle).setCurrentState(Lifecycle.State.CREATED);
}
super.onSaveInstanceState(outState);
mSavedStateRegistryController.performSave(outState);
}
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mSavedStateRegistryController.performRestore(savedInstanceState);
ReportFragment.injectIfNeededIn(this);
if (mContentLayoutId != 0) {
setContentView(mContentLayoutId);
}
}
SavedStateRegistry
private SafeIterableMap<String, SavedStateProvider> mComponents =
new SafeIterableMap<>();
public void registerSavedStateProvider(@NonNull String key,
@NonNull SavedStateProvider provider) {
SavedStateProvider previous = mComponents.putIfAbsent(key, provider);
if (previous != null) {
throw new IllegalArgumentException("SavedStateProvider with the given key is"
+ " already registered");
}
}
@MainThread
void performSave(@NonNull Bundle outBundle) {
Bundle components = new Bundle();
if (mRestoredState != null) {
components.putAll(mRestoredState);
}
for (Iterator<Map.Entry<String, SavedStateProvider>> it =
mComponents.iteratorWithAdditions(); it.hasNext(); ) {
Map.Entry<String, SavedStateProvider> entry1 = it.next();
components.putBundle(entry1.getKey(), entry1.getValue().saveState());
}
outBundle.putBundle(SAVED_COMPONENTS_KEY, components);
}
@MainThread
void performRestore(@NonNull Lifecycle lifecycle, @Nullable Bundle savedState) {
if (mRestored) {
throw new IllegalStateException("SavedStateRegistry was already restored.");
}
if (savedState != null) {
mRestoredState = savedState.getBundle(SAVED_COMPONENTS_KEY);
}
lifecycle.addObserver(new GenericLifecycleObserver() {
@Override
public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
if (event == Lifecycle.Event.ON_START) {
mAllowingSavingState = true;
} else if (event == Lifecycle.Event.ON_STOP) {
mAllowingSavingState = false;
}
}
});
mRestored = true;
}
SavedStateHandleController, SavedStateHandle
public final class SavedStateHandle {
final Map<String, Object> mRegular;
private final Map<String, SavingStateLiveData<?>> mLiveDatas = new HashMap<>();
private static final String VALUES = "values";
private static final String KEYS = "keys";
private final SavedStateProvider mSavedStateProvider = new SavedStateProvider() {
@SuppressWarnings("unchecked")
@NonNull
@Override
public Bundle saveState() {
Set<String> keySet = mRegular.keySet();
ArrayList keys = new ArrayList(keySet.size());
ArrayList value = new ArrayList(keys.size());
for (String key : keySet) {
keys.add(key);
value.add(mRegular.get(key));
}
Bundle res = new Bundle();
// "parcelable" arraylists - lol
res.putParcelableArrayList("keys", keys);
res.putParcelableArrayList("values", value);
return res;
}
};
static SavedStateHandle createHandle(@Nullable Bundle restoredState,
@Nullable Bundle defaultState) {
if (restoredState == null && defaultState == null) {
return new SavedStateHandle();
}
Map<String, Object> state = new HashMap<>();
if (defaultState != null) {
for (String key : defaultState.keySet()) {
state.put(key, defaultState.get(key));
}
}
if (restoredState == null) {
return new SavedStateHandle(state);
}
ArrayList keys = restoredState.getParcelableArrayList(KEYS);
ArrayList values = restoredState.getParcelableArrayList(VALUES);
if (keys == null || values == null || keys.size() != values.size()) {
throw new IllegalStateException("Invalid bundle passed as restored state");
}
for (int i = 0; i < keys.size(); i++) {
state.put((String) keys.get(i), values.get(i));
}
return new SavedStateHandle(state);
}
@MainThread
@NonNull
public <T> MutableLiveData<T> getLiveData(@NonNull String key) {
return getLiveDataInternal(key, false, null);
}
@NonNull
private <T> MutableLiveData<T> getLiveDataInternal(
@NonNull String key,
boolean hasInitialValue,
@Nullable T initialValue) {
MutableLiveData<T> liveData = (MutableLiveData<T>) mLiveDatas.get(key);
if (liveData != null) {
return liveData;
}
SavingStateLiveData<T> mutableLd;
// double hashing but null is valid value
if (mRegular.containsKey(key)) {
mutableLd = new SavingStateLiveData<>(this, key, (T) mRegular.get(key));
} else if (hasInitialValue) {
mutableLd = new SavingStateLiveData<>(this, key, initialValue);
} else {
mutableLd = new SavingStateLiveData<>(this, key);
}
mLiveDatas.put(key, mutableLd);
return mutableLd;
}
static class SavingStateLiveData<T> extends MutableLiveData<T> {
private String mKey;
private SavedStateHandle mHandle;
SavingStateLiveData(SavedStateHandle handle, String key, T value) {
super(value);
mKey = key;
mHandle = handle;
}
SavingStateLiveData(SavedStateHandle handle, String key) {
super();
mKey = key;
mHandle = handle;
}
@Override
public void setValue(T value) {
if (mHandle != null) {
mHandle.mRegular.put(mKey, value);
}
super.setValue(value);
}
void detach() {
mHandle = null;
}
}
private static final Class[] ACCEPTABLE_CLASSES = new Class[]{
//baseBundle
boolean.class,
boolean[].class,
double.class,
double[].class,
int.class,
int[].class,
long.class,
long[].class,
String.class,
String[].class,
//bundle
Binder.class,
Bundle.class,
byte.class,
byte[].class,
char.class,
char[].class,
CharSequence.class,
CharSequence[].class,
// type erasure ¯\_(ツ)_/¯, we won't eagerly check elements contents
ArrayList.class,
float.class,
float[].class,
Parcelable.class,
Parcelable[].class,
Serializable.class,
short.class,
short[].class,
SparseArray.class,
(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP ? Size.class : int.class),
(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP ? SizeF.class : int.class),
};
SavedStateViewModelFactory
@NonNull
@Override
public <T extends ViewModel> T create(@NonNull String key, @NonNull Class<T> modelClass) {
boolean isAndroidViewModel = AndroidViewModel.class.isAssignableFrom(modelClass);
Constructor<T> constructor;
if (isAndroidViewModel) {
constructor = findMatchingConstructor(modelClass, ANDROID_VIEWMODEL_SIGNATURE);
} else {
constructor = findMatchingConstructor(modelClass, VIEWMODEL_SIGNATURE);
}
// doesn't need SavedStateHandle
if (constructor == null) {
return mFactory.create(modelClass);
}
SavedStateHandleController controller = SavedStateHandleController.create(
mSavedStateRegistry, mLifecycle, key, mDefaultArgs);
try {
T viewmodel;
if (isAndroidViewModel) {
viewmodel = constructor.newInstance(mApplication, controller.getHandle());
} else {
viewmodel = constructor.newInstance(controller.getHandle());
}
viewmodel.setTagIfAbsent(TAG_SAVED_STATE_HANDLE_CONTROLLER, controller);
return viewmodel;
} catch (IllegalAccessException e) {
throw new RuntimeException("Failed to access " + modelClass, e);
} catch (InstantiationException e) {
throw new RuntimeException("A " + modelClass + " cannot be instantiated.", e);
} catch (InvocationTargetException e) {
throw new RuntimeException("An exception happened in constructor of "
+ modelClass, e.getCause());
}
}
SavedStateHandleController
static SavedStateHandleController create(SavedStateRegistry registry, Lifecycle lifecycle,
String key, Bundle defaultArgs) {
Bundle restoredState = registry.consumeRestoredStateForKey(key);
SavedStateHandle handle = SavedStateHandle.createHandle(restoredState, defaultArgs);
SavedStateHandleController controller = new SavedStateHandleController(key, handle);
controller.attachToLifecycle(registry, lifecycle);
tryToAddRecreator(registry, lifecycle);
return controller;
}
void attachToLifecycle(SavedStateRegistry registry, Lifecycle lifecycle) {
if (mIsAttached) {
throw new IllegalStateException("Already attached to lifecycleOwner");
}
mIsAttached = true;
lifecycle.addObserver(this);
registry.registerSavedStateProvider(mKey, mHandle.savedStateProvider());
}
使用AAC的误区
1、泄露 Fragment 中的 LiveData 观察者
比如在ViewPager里,只销毁Fragment 的View,本身不销毁时, 那么在使用LiveData 时需要使用getViewLifeCycleOwner
new LiveData<>().observe(getViewLifecycleOwner(), new Observer<Object>() {});
这样在Fragment 走到onDestroyView 时,liveData 就会将该Observer移除。
2、每次屏幕旋转后都重新加载数据
通常,我们在 Activity#onCreate(),或 Fragment#onCreateView() 及以后的生命周期方法中创建ViewModel 对象并初始化数据。那么在每次屏幕旋转后,即使 ViewModel 实例不会重新创建,也可能导致重新加载数据,而在大多数情况下,数据并没有变化,所以这种重新加载没有意义。
最简单的解决方案,就是将加载数据的逻辑,写在 ViewModel 的构造方法中, 对于在实际需要的地方才开始加载数据,还是正常写法就可以。
3、 ViewModel 不要持有Activity 或Fragment的引用