jetpack原理分析(lifecycle、viewmodel、livedata小结)

本文讲的是lifecycle、viewmodel、livedata的简单原理~

先来段小结

Lifecycle原理:

Lifecycle可以用来观察activity和fragment的生命周期。

  • 在api>=29之前,activity是通过执行生命周期的时候回调LifecyclerCallbacks;29之后,activity会添加一个没有UI的ReportFragment,间接获得Activity的生命周期事件后,通过LifecycleRegistry用接收到的event计算出当前state保存下来并给每个观察者发送通知事件,观察者是一个封装的带state的ObserverWithState类。
  • Fragment是直接在生命周期里调用LifecycleRegistry分发事件。

ViewModel原理:

  • 在activity销毁的时候会执行onRetainNonConfigurationInstance方法,在这个方法里保存Activity、fragment、和子fragment的viewmodel到viewmodelStore的hashmap里,然后在Activity恢复的时候用getLastNonConfigurationInstance方法里通过key从hashmap再取出Viewmodel。
  • Viewmodel通过lifecycle监听Activity的生命周期变化,在Activity创建的时候保证数据取出,销毁时移除所有的viewmodel数据。

Livedata原理:

  • 观察者:livedata的observe()会创建一个LifecycleBoundObserver 观察者。通过lifecycle观察activity 的state为destroy的时候把自己移除掉。不是destroy则给自己分发已存储的data粘性数据。
  • 被观察者:livedata的setValue会调用dispatchingValue方法遍历所有的观察者回调data。观察者是observe()方法时添加进集合的。postValue()是通过主线程handler调用setValue()。

正式开始

Lifecycle

使用:
//实现了LifecycleOwner 接口的Activity中调用getLifecycle,获得LifecycleRegistry,调用其addObserver().
lifecycle.addObserver(object : DefaultLifecycleObserver {
        override fun onCreate(owner: LifecycleOwner) {}
//……
}
原理分析:

LifecycleOwner 接口用于标记其实现类具备 Lifecycle 对象,实现了该接口即意味着实现类具有生命周期。我们日常使用的 androidx.appcompat.app.AppCompatActivity 和 androidx.fragment.app.Fragment 均实现了该接口。

public interface LifecycleOwner {
    @NonNull
	Lifecycle getLifecycle();
}
public class ComponentActivity|Fragment implements  LifecycleOwner {
    @Override
    public Lifecycle getLifecycle() {
        return mLifecycleRegistry;
	}
}
  1. 设备的系统版本号大于等于29。会向 Activity 注册一个 LifecycleCallbacks ,以此来直接获得各个生命周期事件的回调。Activity生命周期回调的时候会回调LifecycleCallbacks的对应生命周期方法。
  2. 设备的系统版本号小于 29。会通过向 Activity 添加一个无 UI 界面的 Fragment(即 ReportFragment),间接获得 Activity 的各个生命周期事件的回调。
  3. 之所以会进行这两种情况区分,是因为 Activity.registerActivityLifecycleCallbacks 是 SDK 29 开始 android.app.Activity 新添加的方法。

LifecycleRegistry#addObserver:

public void addObserver(@NonNull LifecycleObserver observer) {
        State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
//将传入的 observer 对象包装为 ObserverWithState 类型
        ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
        ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);

        if (previous != null) {
            //如果 observer 之前已经传进来过了,则不重复添加,直接返回
            return;
        }
        LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
        if (lifecycleOwner == null) {
            //如果 LifecycleOwner 对象已经被回收了,则直接返回
            return;
        }

        //如果 isReentrance 为 true,意味着当前存在重入的情况:
        //1. mAddingObserverCounter != 0。会出现这种情况,是由于开发者先添加了一个 LifecycleObserver ,当还在向其回调事件的过程中,在回调方法里又再次调用了 addObserver 方法添加了一个新的 LifecycleObserver
        //2.mHandlingEvent 为 true。即此时正处于向外回调 Lifecycle.Event 的状态
        boolean isReentrance = mAddingObserverCounter != 0 || mHandlingEvent;

        State targetState = calculateTargetState(observer);

        //递增加一,标记当前正处于向新添加的 LifecycleObserver 回调 Event 值的过程
        mAddingObserverCounter++;

        //statefulObserver.mState.compareTo(targetState) < 0 成立的话说明 State 值还没遍历到目标状态
        //mObserverMap.contains(observer) 成立的话说明 observer 还没有并移除
        //因为有可能在遍历过程中开发者主动在回调方法里将 observer 给移除掉了,所以这里每次循环都检查下
        while ((statefulObserver.mState.compareTo(targetState) < 0
                && mObserverMap.contains(observer))) {
           
            //向 observer 回调进入“statefulObserver.mState”前需要收到的 Event 值
//由于当添加 LifecycleObserver 时 Lifecycle 可能已经处于非 INITIALIZED 状态了,所以需要通过循环检查的方式来向 ObserverWithState 逐步下发 Event 值。
            statefulObserver.dispatchEvent(lifecycleOwner, upEvent(statefulObserver.mState));
        }
        if (!isReentrance) {
            sync();
        }
        mAddingObserverCounter--;
    }

ReportFragment:

@Override
public void onStart() {
    super.onStart();
    dispatchStart(mProcessListener);
    dispatch(Lifecycle.Event.ON_START);
}
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);
        }
    }
}

Fragment 是在其生命周期方法中直接调用了内部LifecycleRegistry的handleLifecycleEvent进行生命周期事件分发。该方法会根据接收到的 Event 值换算出对应的 State 值,然后更新本地的 mState,再向所有 Observer 进行事件通知,最终还是会调用到 ObserverWithState 的 dispatchEvent 方法。

Fragment :

public class Fragment implement LifecycleOwner{     
    LifecycleRegistry mLifecycleRegistry;      
    @Override
    public Lifecycle getLifecycle() {
        return mLifecycleRegistry;
    }
     void performStart() {
        ...
        onStart();
        mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START);
        ...
    }  
}

LifecycleRegistry:

public void handleLifecycleEvent(@NonNull Lifecycle.Event event) {
    enforceMainThreadIfNeeded("handleLifecycleEvent");
    moveToState(event.getTargetState());
}
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;
        // no need to check eldest for nullability, because isSynced does it for us.
        if (mState.compareTo(mObserverMap.eldest().getValue().mState) < 0) {
            backwardPass(lifecycleOwner);
        }
        Map.Entry<LifecycleObserver, ObserverWithState> newest = mObserverMap.newest();
        if (!mNewEventOccurred && newest != null
                && mState.compareTo(newest.getValue().mState) > 0) {
            forwardPass(lifecycleOwner);
        }
    }
    mNewEventOccurred = false;
}
private void forwardPass(LifecycleOwner lifecycleOwner) {
    Iterator<Map.Entry<LifecycleObserver, ObserverWithState>> ascendingIterator =
            mObserverMap.iteratorWithAdditions();
    while (ascendingIterator.hasNext() && !mNewEventOccurred) {
        Map.Entry<LifecycleObserver, ObserverWithState> entry = ascendingIterator.next();
        ObserverWithState observer = entry.getValue();
        while ((observer.mState.compareTo(mState) < 0 && !mNewEventOccurred
                && mObserverMap.contains(entry.getKey()))) {
            pushParentState(observer.mState);
            final Event event = Event.upFrom(observer.mState);
            if (event == null) {
                throw new IllegalStateException("no event up from " + observer.mState);
            }
            observer.dispatchEvent(lifecycleOwner, event);
            popParentState();
        }
    }
}

Event 用于抽象 Activity/Fragment 的生命周期事件。例如,当 Activity 的 onCreate 方法被回调时就会被抽象为 ON_CREATE事件。
State 用于标记 Lifecycle 的当前生命周期状态。例如,当 Activity 即将回调 onDestory 方法时则处于 DESTROYED 状态
在这里插入图片描述

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 = event.getTargetState();
        mState = min(mState, newState);
        mLifecycleObserver.onStateChanged(owner, event);
        mState = newState;
    }
}

参考文章:
lifecycle源码注解拷贝小红军storm 大佬较多,详情移步:
https://www.jianshu.com/p/cc356af30411

Viewmodel

使用场景:
  • 场景一:我们开发的 APP 可以转屏,转屏后将触发 Controller(Activity or Fragment) 的重建,为了维护转屏前后数据的一致性,我们要么将需要维护的数据以 Bundle 的形式在 onSaveInstance 中保存,必要的时候需要对复合数据实现繁琐的 Parceable 接口,如果数据量太大则我们必须将数据持久化,在转屏后重新拉取数据(from database or networks);
  • 场景二:我们的 Activity 中同时维护了多个 Fragment,每个 Fragment 需要共享一些数据,传统的做法是由宿主 Activity 持有共享数据,并暴露数据获取接口给各个寄生 Fragment。
原理:

ComponentActivity:

getLifecycle().addObserver(new LifecycleEventObserver() {
    @Override
    public void onStateChanged(@NonNull LifecycleOwner source,
            @NonNull Lifecycle.Event event) {
	//观察到 Activity 被销毁
        if (event == Lifecycle.Event.ON_DESTROY) {
            // Clear out the available context
            mContextAwareHelper.clearAvailableContext();
            // And clear the ViewModelStore
            if (!isChangingConfigurations()) {
                getViewModelStore().clear();
            }
        }
    }
});
getLifecycle().addObserver(new LifecycleEventObserver() {
    @Override
    public void onStateChanged(@NonNull LifecycleOwner source,
            @NonNull Lifecycle.Event event) {
        ensureViewModelStore();
        getLifecycle().removeObserver(this);
    }
});
/**
 * Retain all appropriate non-config state.  You can NOT
 * override this yourself!  Use a {@link androidx.lifecycle.ViewModel} if you want to
 * retain your own non config state.
 */
@Override
@Nullable
@SuppressWarnings("deprecation")
public final Object onRetainNonConfigurationInstance() {
    // Maintain backward compatibility.
    Object custom = onRetainCustomNonConfigurationInstance();
    ViewModelStore viewModelStore = mViewModelStore;
    NonConfigurationInstances nci = new NonConfigurationInstances();
    nci.custom = custom;
    nci.viewModelStore = viewModelStore;
    return nci;
}
void ensureViewModelStore() {
    if (mViewModelStore == null) {
        NonConfigurationInstances nc =
                (NonConfigurationInstances) getLastNonConfigurationInstance();
        if (nc != null) {
            // Restore the ViewModelStore from NonConfigurationInstances
            // 屏幕旋转在这里恢复
            mViewModelStore = nc.viewModelStore;
        }
        if (mViewModelStore == null) {
            mViewModelStore = new ViewModelStore();
        }
    }
}
  • 屏幕旋转前,Activity销毁时:
    ComponentActivity调用onRetainNonConfigurationInstance()方法,将要销毁的Activity的mViewModelStore转化为NonConfigurationInstances对象存储。
  • 在Activity启动或者再次创建Viewmodel时:
    都会调用ensureViewModelStore()方法通过getLastNonConfigurationInstance()恢复mViewModelStore实例对象,最后根据对应的key拿到销毁前对应的ViewModel实例。
    在这里插入图片描述

处于顶层的 ViewModelStore 依附于 FragmentActivity,它除了保存用户级的 ViewModel 以外,还保存其儿子 Fragment 的 FragmentManagerViewModel。
ViewModelStore 里面就是一个HashMap,用于缓存ViewModel实例对象。
ViewModelStore 与具体的 Controller (Activity or Fragment) 绑定,并与宿主 Controller 俱生俱灭,所以这就解释了为何 ViewModel 与宿主 Controller 的生命周期是一样长了,因为缓存它的 ViewModelStore 与宿主 Controller 寿命相等;
参考文章:
https://www.cnblogs.com/cubbychat/p/15023207.html

Livedata

原理

Livedata:

public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
	LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
	mObservers.putIfAbsent(observer, wrapper);

//LifecycleBoundObserver 是一个观察者,去观察activity的生命周期。当被观察者activity生命周期为destroyed的时候,会执行removeObserver方法,将观察者从Lifecycle被观察者列表中删除。
	owner.getLifecycle().addObserver(wrapper);//观察者身份
}

LifecycleBoundObserver :

class LifecycleBoundObserver extends ObserverWrapper implements LifecycleEventObserver {final Observer<? super T> mObserver;//父类成员变量
        ObserverWrapper(Observer<? super T> observer) {//父类构造方法
            mObserver = observer;
        }
@Override
public void onStateChanged(@NonNull LifecycleOwner source,
        @NonNull Lifecycle.Event event) {
    Lifecycle.State currentState = mOwner.getLifecycle().getCurrentState();
    if (currentState == DESTROYED) {
        removeObserver(mObserver);
        return;
    }
    while (prevState != currentState) {
//粘性事件原因(lifecycle会将livedata.observe()之前的state都分发一次)
        activeStateChanged(shouldBeActive());
    }
}
void activeStateChanged(boolean newActive) {
    if (newActive == mActive) {
        return;
    }
    // immediately set active state, so we'd never dispatch anything to inactive
    // owner
    mActive = newActive;
    changeActiveCounter(mActive ? 1 : -1);
    if (mActive) {
//调用livedata的方法分发数据
        dispatchingValue(this);//粘性事件分发数据(只分发给当前新加入的Observer)
    }
}
@Override
boolean shouldBeActive() {
    return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
}

Livedata:

@MainThread
protected void setValue(T value) {//被观察者身份
    assertMainThread("setValue");
    mVersion++;
    mData = value;
    dispatchingValue(null);//观察的值变化时分发数据
}
void dispatchingValue(@Nullable ObserverWrapper initiator) {
            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;
                    }
                }
            }
}
private void considerNotify(ObserverWrapper observer) {
     if (!observer.mActive) {
         return;
     }
if (!observer.shouldBeActive()) {
         observer.activeStateChanged(false);
         return;
     }
    observer.mObserver.onChanged((T) mData);
}

postValue():就是通过主线程的handler切换到主线程再调用setValue()方法

private final Runnable mPostValueRunnable = new Runnable() {
    @SuppressWarnings("unchecked")
    @Override
    public void run() {
        setValue((T) newValue);
    }
};
protected void postValue(T value) {
    //mMainHandler = createAsync(Looper.getMainLooper());
    ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值