LiveData和ViewModel源码学习

简介: LiveData和ViewModel源码学习
LiveData
ObserverWrapper 数据观察者
LifecycleEventObserver 生命周期观察者
  1. 活跃状态接受并更新数据 刷新页面数据
  2. 非活跃状态暂停接收数据 防止崩溃,
  3. 销毁状态的时候移除观察者 防止内存泄漏
  1. 数据可以监听
  1. 数据倒灌,就是先发送数据,通过生命周期响应来触发change
  1. 数据粘性,先发送数据,后订阅的也能收到数据
  1. 为什么能感知生命周期和数据观察者 因为把传入的观察者通过LifecicleBoundObserver包了一层

     LifecicleBoundObserver继承了LifecicleEventObserver和ObserverWrapper,然后添加到lifecicle和livedata中



package androidx.lifecycle;

import androidx.annotation.MainThread;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.arch.core.executor.ArchTaskExecutor;
import androidx.arch.core.internal.SafeIterableMap;
import androidx.lifecycle.Lifecycle.State;
import java.util.Iterator;
import java.util.Map;

public abstract class LiveData<T> {
    final Object mDataLock = new Object();
    static final int START_VERSION = -1;
    static final Object NOT_SET = new Object();
    private SafeIterableMap<Observer<? super T>, LiveData<T>.ObserverWrapper> mObservers = new SafeIterableMap();
    int mActiveCount = 0;
    private volatile Object mData;
    volatile Object mPendingData;
    private int mVersion;
    private boolean mDispatchingValue;
    private boolean mDispatchInvalidated;
    private final Runnable mPostValueRunnable;

    public LiveData(T value) {
        this.mPendingData = NOT_SET;
        this.mPostValueRunnable = new NamelessClass_1();
        this.mData = value;
        this.mVersion = 0;
    }

    public LiveData() {
        this.mPendingData = NOT_SET;

        class NamelessClass_1 implements Runnable {
            NamelessClass_1() {
            }

            public void run() {
                Object newValue;
                synchronized(LiveData.this.mDataLock) {
                    newValue = LiveData.this.mPendingData;
                    LiveData.this.mPendingData = LiveData.NOT_SET;
                }

                LiveData.this.setValue(newValue);
            }
        }

        this.mPostValueRunnable = new NamelessClass_1();
        this.mData = NOT_SET;
        this.mVersion = -1;
    }

    private void considerNotify(LiveData<T>.ObserverWrapper observer) {
        if (observer.mActive) {
            if (!observer.shouldBeActive()) {
                observer.activeStateChanged(false);
            } else if (observer.mLastVersion < this.mVersion) {
                observer.mLastVersion = this.mVersion;
                observer.mObserver.onChanged(this.mData);
            }
        }
    }

    void dispatchingValue(@Nullable LiveData<T>.ObserverWrapper initiator) {
        if (this.mDispatchingValue) {
            this.mDispatchInvalidated = true;
        } else {
            this.mDispatchingValue = true;

            do {
                this.mDispatchInvalidated = false;
                if (initiator != null) {
                    this.considerNotify(initiator);
                    initiator = null;
                } else {
                    Iterator<Map.Entry<Observer<? super T>, LiveData<T>.ObserverWrapper>> iterator = this.mObservers.iteratorWithAdditions();

                    while(iterator.hasNext()) {
                        this.considerNotify((ObserverWrapper)((Map.Entry)iterator.next()).getValue());
                        if (this.mDispatchInvalidated) {
                            break;
                        }
                    }
                }
            } while(this.mDispatchInvalidated);

            this.mDispatchingValue = false;
        }
    }

    @MainThread
    public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
        assertMainThread("observe");
        if (owner.getLifecycle().getCurrentState() != State.DESTROYED) {
            LiveData<T>.LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
            LiveData<T>.ObserverWrapper existing = (ObserverWrapper)this.mObservers.putIfAbsent(observer, wrapper);
            if (existing != null && !existing.isAttachedTo(owner)) {
                throw new IllegalArgumentException("Cannot add the same observer with different lifecycles");
            } else if (existing == null) {
                owner.getLifecycle().addObserver(wrapper);
            }
        }
    }

    @MainThread
    public void observeForever(@NonNull Observer<? super T> observer) {
        assertMainThread("observeForever");
        LiveData<T>.AlwaysActiveObserver wrapper = new AlwaysActiveObserver(observer);
        LiveData<T>.ObserverWrapper existing = (ObserverWrapper)this.mObservers.putIfAbsent(observer, wrapper);
        if (existing instanceof LifecycleBoundObserver) {
            throw new IllegalArgumentException("Cannot add the same observer with different lifecycles");
        } else if (existing == null) {
            wrapper.activeStateChanged(true);
        }
    }

    @MainThread
    public void removeObserver(@NonNull Observer<? super T> observer) {
        assertMainThread("removeObserver");
        LiveData<T>.ObserverWrapper removed = (ObserverWrapper)this.mObservers.remove(observer);
        if (removed != null) {
            removed.detachObserver();
            removed.activeStateChanged(false);
        }
    }

    @MainThread
    public void removeObservers(@NonNull LifecycleOwner owner) {
        assertMainThread("removeObservers");
        Iterator var2 = this.mObservers.iterator();

        while(var2.hasNext()) {
            Map.Entry<Observer<? super T>, LiveData<T>.ObserverWrapper> entry = (Map.Entry)var2.next();
            if (((ObserverWrapper)entry.getValue()).isAttachedTo(owner)) {
                this.removeObserver((Observer)entry.getKey());
            }
        }

    }

    protected void postValue(T value) {
        boolean postTask;
        synchronized(this.mDataLock) {
            postTask = this.mPendingData == NOT_SET;
            this.mPendingData = value;
        }

        if (postTask) {
            ArchTaskExecutor.getInstance().postToMainThread(this.mPostValueRunnable);
        }
    }

    @MainThread
    protected void setValue(T value) {
        assertMainThread("setValue");
        ++this.mVersion;
        this.mData = value;
        this.dispatchingValue((ObserverWrapper)null);
    }

    @Nullable
    public T getValue() {
        Object data = this.mData;
        return data != NOT_SET ? data : null;
    }

    int getVersion() {
        return this.mVersion;
    }

    protected void onActive() {
    }

    protected void onInactive() {
    }

    public boolean hasObservers() {
        return this.mObservers.size() > 0;
    }

    public boolean hasActiveObservers() {
        return this.mActiveCount > 0;
    }

    static void assertMainThread(String methodName) {
        if (!ArchTaskExecutor.getInstance().isMainThread()) {
            throw new IllegalStateException("Cannot invoke " + methodName + " on a background thread");
        }
    }

    private class AlwaysActiveObserver extends LiveData<T>.ObserverWrapper {
        AlwaysActiveObserver(Observer<? super T> observer) {
            super(observer);
        }

        boolean shouldBeActive() {
            return true;
        }
    }

    private abstract class ObserverWrapper {
        final Observer<? super T> mObserver;
        boolean mActive;
        int mLastVersion = -1;

        ObserverWrapper(Observer<? super T> observer) {
            this.mObserver = observer;
        }

        abstract boolean shouldBeActive();

        boolean isAttachedTo(LifecycleOwner owner) {
            return false;
        }

        void detachObserver() {
        }

        void activeStateChanged(boolean newActive) {
            if (newActive != this.mActive) {
                this.mActive = newActive;
                boolean wasInactive = LiveData.this.mActiveCount == 0;
                LiveData var10000 = LiveData.this;
                var10000.mActiveCount += this.mActive ? 1 : -1;
                if (wasInactive && this.mActive) {
                    LiveData.this.onActive();
                }

                if (LiveData.this.mActiveCount == 0 && !this.mActive) {
                    LiveData.this.onInactive();
                }

                if (this.mActive) {
                    LiveData.this.dispatchingValue(this);
                }

            }
        }
    }

    class LifecycleBoundObserver extends LiveData<T>.ObserverWrapper implements LifecycleEventObserver {
        @NonNull
        final LifecycleOwner mOwner;

        LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer<? super T> observer) {
            super(observer);
            this.mOwner = owner;
        }

        boolean shouldBeActive() {
            return this.mOwner.getLifecycle().getCurrentState().isAtLeast(State.STARTED);
        }

        public void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event) {
            if (this.mOwner.getLifecycle().getCurrentState() == State.DESTROYED) {
                LiveData.this.removeObserver(this.mObserver);
            } else {
                this.activeStateChanged(this.shouldBeActive());
            }
        }

        boolean isAttachedTo(LifecycleOwner owner) {
            return this.mOwner == owner;
        }

        void detachObserver() {
            this.mOwner.getLifecycle().removeObserver(this);
        }
    }
}

ViewModel

1.为什么ViewModel生命周期比activity长

attach(Acitivity)->mLastNonConfigurationInstances(ActivityClientRecord)-> 恢复

performDestoryActivity(ActivityThread)-> retainNonConfigurationInstances(Activity)- onRetainConfigurationInstances(ComponentActivity)->mLastNonConfigurationInstances 保存

ViewModelStore
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package androidx.lifecycle;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

public class ViewModelStore {
    private final HashMap<String, ViewModel> mMap = new HashMap();

    public ViewModelStore() {
    }

    final void put(String key, ViewModel viewModel) {
        ViewModel oldViewModel = (ViewModel)this.mMap.put(key, viewModel);
        if (oldViewModel != null) {
            oldViewModel.onCleared();
        }

    }

    final ViewModel get(String key) {
        return (ViewModel)this.mMap.get(key);
    }

    Set<String> keys() {
        return new HashSet(this.mMap.keySet());
    }

    public final void clear() {
        Iterator var1 = this.mMap.values().iterator();

        while(var1.hasNext()) {
            ViewModel vm = (ViewModel)var1.next();
            vm.clear();
        }

        this.mMap.clear();
    }
}

ViewModelProvider


package androidx.lifecycle;

import android.app.Application;
import androidx.annotation.MainThread;
import androidx.annotation.NonNull;
import java.lang.reflect.InvocationTargetException;

public class ViewModelProvider {
    private static final String DEFAULT_KEY = "androidx.lifecycle.ViewModelProvider.DefaultKey";
    private final Factory mFactory;
    private final ViewModelStore mViewModelStore;

    public ViewModelProvider(@NonNull ViewModelStoreOwner owner) {
        this((ViewModelStore)owner.getViewModelStore(), (Factory)(owner instanceof HasDefaultViewModelProviderFactory ? ((HasDefaultViewModelProviderFactory)owner).getDefaultViewModelProviderFactory() : ViewModelProvider.NewInstanceFactory.getInstance()));
    }

    public ViewModelProvider(@NonNull ViewModelStoreOwner owner, @NonNull Factory factory) {
        this(owner.getViewModelStore(), factory);
    }

    public ViewModelProvider(@NonNull ViewModelStore store, @NonNull Factory factory) {
        this.mFactory = factory;
        this.mViewModelStore = store;
    }

    @NonNull
    @MainThread
    public <T extends ViewModel> T get(@NonNull Class<T> modelClass) {
        String canonicalName = modelClass.getCanonicalName();
        if (canonicalName == null) {
            throw new IllegalArgumentException("Local and anonymous classes can not be ViewModels");
        } else {
            return this.get("androidx.lifecycle.ViewModelProvider.DefaultKey:" + canonicalName, modelClass);
        }
    }

    @NonNull
    @MainThread
    public <T extends ViewModel> T get(@NonNull String key, @NonNull Class<T> modelClass) {
        ViewModel viewModel = this.mViewModelStore.get(key);
        if (modelClass.isInstance(viewModel)) {
            if (this.mFactory instanceof OnRequeryFactory) {
                ((OnRequeryFactory)this.mFactory).onRequery(viewModel);
            }

            return viewModel;
        } else {
            if (viewModel != null) {
            }

            if (this.mFactory instanceof KeyedFactory) {
                viewModel = ((KeyedFactory)((KeyedFactory)this.mFactory)).create(key, modelClass);
            } else {
                viewModel = this.mFactory.create(modelClass);
            }

            this.mViewModelStore.put(key, viewModel);
            return viewModel;
        }
    }

    public static class AndroidViewModelFactory extends NewInstanceFactory {
        private static AndroidViewModelFactory sInstance;
        private Application mApplication;

        @NonNull
        public static AndroidViewModelFactory getInstance(@NonNull Application application) {
            if (sInstance == null) {
                sInstance = new AndroidViewModelFactory(application);
            }

            return sInstance;
        }

        public AndroidViewModelFactory(@NonNull Application application) {
            this.mApplication = application;
        }

        @NonNull
        public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
            if (AndroidViewModel.class.isAssignableFrom(modelClass)) {
                try {
                    return (ViewModel)modelClass.getConstructor(Application.class).newInstance(this.mApplication);
                } catch (NoSuchMethodException var3) {
                    throw new RuntimeException("Cannot create an instance of " + modelClass, var3);
                } catch (IllegalAccessException var4) {
                    throw new RuntimeException("Cannot create an instance of " + modelClass, var4);
                } catch (InstantiationException var5) {
                    throw new RuntimeException("Cannot create an instance of " + modelClass, var5);
                } catch (InvocationTargetException var6) {
                    throw new RuntimeException("Cannot create an instance of " + modelClass, var6);
                }
            } else {
                return super.create(modelClass);
            }
        }
    }

    public static class NewInstanceFactory implements Factory {
        private static NewInstanceFactory sInstance;

        public NewInstanceFactory() {
        }

        @NonNull
        static NewInstanceFactory getInstance() {
            if (sInstance == null) {
                sInstance = new NewInstanceFactory();
            }

            return sInstance;
        }

        @NonNull
        public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
            try {
                return (ViewModel)modelClass.newInstance();
            } catch (InstantiationException var3) {
                throw new RuntimeException("Cannot create an instance of " + modelClass, var3);
            } catch (IllegalAccessException var4) {
                throw new RuntimeException("Cannot create an instance of " + modelClass, var4);
            }
        }
    }

    abstract static class KeyedFactory extends OnRequeryFactory implements Factory {
        KeyedFactory() {
        }

        @NonNull
        public abstract <T extends ViewModel> T create(@NonNull String var1, @NonNull Class<T> var2);

        @NonNull
        public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
            throw new UnsupportedOperationException("create(String, Class<?>) must be called on implementaions of KeyedFactory");
        }
    }

    static class OnRequeryFactory {
        OnRequeryFactory() {
        }

        void onRequery(@NonNull ViewModel viewModel) {
        }
    }

    public interface Factory {
        @NonNull
        <T extends ViewModel> T create(@NonNull Class<T> var1);
    }
}

ViewModelStoreOwner
public interface ViewModelStoreOwner {
    @NonNull
    ViewModelStore getViewModelStore();
}

ComponentActivity
NonConfigurationInstances
  @Nullable
    public final Object onRetainNonConfigurationInstance() {
        Object custom = this.onRetainCustomNonConfigurationInstance();
        ViewModelStore viewModelStore = this.mViewModelStore;
        NonConfigurationInstances nci;
        if (viewModelStore == null) {
            nci = (NonConfigurationInstances)this.getLastNonConfigurationInstance();
            if (nci != null) {
                viewModelStore = nci.viewModelStore;
            }
        }

        if (viewModelStore == null && custom == null) {
            return null;
        } else {
            nci = new NonConfigurationInstances();
            nci.custom = custom;
            nci.viewModelStore = viewModelStore;
            return nci;
        }
    }
     @NonNull
    public ViewModelStore getViewModelStore() {
        if (this.getApplication() == null) {
            throw new IllegalStateException("Your activity is not yet attached to the Application instance. You can't request ViewModel before onCreate call.");
        } else {
            if (this.mViewModelStore == null) {
                NonConfigurationInstances nc = (NonConfigurationInstances)this.getLastNonConfigurationInstance();
                if (nc != null) {
                    this.mViewModelStore = nc.viewModelStore;
                }

                if (this.mViewModelStore == null) {
                    this.mViewModelStore = new ViewModelStore();
                }
            }

            return this.mViewModelStore;
        }
    }
     @NonNull
    public ViewModelProvider.Factory getDefaultViewModelProviderFactory() {
        if (this.getApplication() == null) {
            throw new IllegalStateException("");
        } else {
            if (this.mDefaultFactory == null) {
                this.mDefaultFactory = new SavedStateViewModelFactory(this.getApplication(), this, this.getIntent() != null ? this.getIntent().getExtras() : null);
            }

            return this.mDefaultFactory;
        }
    }
   static final class NonConfigurationInstances {
        Object custom;
        ViewModelStore viewModelStore;

        NonConfigurationInstances() {
        }
    }
Activity attach 恢复
NonConfigurationInstances
  
 @UnsupportedAppUsage
    final void attach(Context context, ActivityThread aThread,
            Instrumentation instr, IBinder token, int ident,
            Application application, Intent intent, ActivityInfo info,
            CharSequence title, Activity parent, String id,
            NonConfigurationInstances lastNonConfigurationInstances,
            Configuration config, String referrer, IVoiceInteractor voiceInteractor,
            Window window, ActivityConfigCallback activityConfigCallback, IBinder assistToken) {
              mLastNonConfigurationInstances = lastNonConfigurationInstances;
            }

 NonConfigurationInstances retainNonConfigurationInstances() {
        Object activity = onRetainNonConfigurationInstance();
        NonConfigurationInstances nci = new NonConfigurationInstances();
        nci.activity = activity;
        nci.children = children;
        nci.fragments = fragments;
        nci.loaders = loaders;
        if (mVoiceInteractor != null) {
            mVoiceInteractor.retainInstance();
            nci.voiceInteractor = mVoiceInteractor;
        }
        return nci;
    }
    static final class NonConfigurationInstances {
        Object activity;
        HashMap<String, Object> children;
        FragmentManagerNonConfig fragments;
        ArrayMap<String, LoaderManager> loaders;
        VoiceInteractor voiceInteractor;
    }

ActivityThread performDestroyActivity 保存
   @UnsupportedAppUsage
    final ArrayMap<IBinder, ActivityClientRecord> mActivities = new ArrayMap<>();
  
   ActivityClientRecord performDestroyActivity(IBinder token, boolean finishing,
            int configChanges, boolean getNonConfigInstance, String reason) {
        ActivityClientRecord r = mActivities.get(token);
        Class<? extends Activity> activityClass = null;
        if (localLOGV) Slog.v(TAG, "Performing finish of " + r);
        if (r != null) {
            activityClass = r.activity.getClass();
            r.activity.mConfigChangeFlags |= configChanges;
            if (finishing) {
                r.activity.mFinished = true;
            }
            performPauseActivityIfNeeded(r, "destroy");
            if (getNonConfigInstance) {
                try {
                    r.lastNonConfigurationInstances
                            = r.activity.retainNonConfigurationInstances();
                } catch (Exception e) {
                    if (!mInstrumentation.onException(r.activity, e)) {
                        throw new RuntimeException(
                                "Unable to retain activity "
                                + r.intent.getComponent().toShortString()
                                + ": " + e.toString(), e);
                    }
                }
            }
         
        return r;
    }


ActivityClientRecord
  public static final class ActivityClientRecord {
        @UnsupportedAppUsage
        public IBinder token;
        Activity.NonConfigurationInstances lastNonConfigurationInstances;
        
 }
相关文章
|
存储 缓存 安全
[笔记]深入解析Windows操作系统《二》系统架构
深入解析Windows操作系统《二》系统架构
1926 0
[笔记]深入解析Windows操作系统《二》系统架构
|
8月前
|
机器学习/深度学习 数据处理
大语言模型中的归一化技术:LayerNorm与RMSNorm的深入研究
本文分析了大规模Transformer架构(如LLama)中归一化技术的关键作用,重点探讨了LayerNorm被RMSNorm替代的原因。归一化通过调整数据量纲保持分布形态不变,提升计算稳定性和收敛速度。LayerNorm通过均值和方差归一化确保数值稳定,适用于序列模型;而RMSNorm仅使用均方根归一化,省略均值计算,降低计算成本并缓解梯度消失问题。RMSNorm在深层网络中表现出更高的训练稳定性和效率,为复杂模型性能提升做出重要贡献。
1685 14
大语言模型中的归一化技术:LayerNorm与RMSNorm的深入研究
|
安全 Java API
ServletRequest类及其使用方法介绍
ServletRequest类及其使用方法介绍
575 6
|
11月前
|
人工智能 自然语言处理 PyTorch
Bamba-9B:基于 Mamba2 架构的仅解码语言模型,旨在提高大型语言模型在推理时的效率
Bamba-9B 是由 IBM、普林斯顿大学、卡内基梅隆大学和伊利诺伊大学香槟分校联合推出的基于 Mamba2 架构的仅解码语言模型。该模型在开放数据集上训练,旨在提高大型语言模型的推理效率,特别是在处理长文本时的内存带宽瓶颈。Bamba-9B 在推理时相较于标准变换器模型展现出 2.5 倍的吞吐量提升和 2 倍的延迟加速。
274 12
Bamba-9B:基于 Mamba2 架构的仅解码语言模型,旨在提高大型语言模型在推理时的效率
ts中interface和type的区别
ts中interface和type的区别
806 61
|
Linux 调度
linux中进程与cpu核的绑定
linux中进程与cpu核的绑定
430 0
IntelliJ IDEA汉化
IntelliJ IDEA汉化
215 0
|
Kubernetes 持续交付 Python
Kubernetes(通常简称为K8s)是一个开源的容器编排系统,用于自动化部署、扩展和管理容器化应用程序。
Kubernetes(通常简称为K8s)是一个开源的容器编排系统,用于自动化部署、扩展和管理容器化应用程序。
|
JavaScript UED
Vue中如何监听窗口尺寸变化?
Vue中如何监听窗口尺寸变化?
1505 4
|
Python
Python pip install修改默认下载路径
Python pip install修改默认下载路径
727 0