当前位置:网站首页>Jetpack ViewModel source analysis

Jetpack ViewModel source analysis

2022-09-23 08:22:19xiangxiongfly915

Jetpack ViewModel源码分析

ViewModel生命周期图

在这里插入图片描述

源码分析

ViewModelStore类

//ViewModelStore本质是一个哈希表,键值对形式
public class ViewModelStore {
    
    
    //key:"androidx.lifecycle.ViewModelProvider.DefaultKey"+ViewModel类名的拼接
    //value:ViewModel对象
    private final HashMap<String, ViewModel> mMap = new HashMap<>();

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

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

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

    //清除内部存储并通知viewmodelThey are no longer used.
    public final void clear() {
    
        for (ViewModel vm : mMap.values()) {
    
            vm.clear();
        }
        mMap.clear();
    }
}

ViewModelProvider类

public open class ViewModelProvider @JvmOverloads constructor(
    private val store: ViewModelStore,
    private val factory: Factory,
    private val defaultCreationExtras: CreationExtras = CreationExtras.Empty,
) {
    

    public constructor(
        owner: ViewModelStoreOwner
    ) : this(owner.viewModelStore, defaultFactory(owner), defaultCreationExtras(owner))

    @MainThread
    public open operator fun <T : ViewModel> get(modelClass: Class<T>): T {
    
        val canonicalName = modelClass.canonicalName
        ?: throw IllegalArgumentException("Local and anonymous classes can not be ViewModels")
        //Use class name concatenation as the replacementkey
        return get("$DEFAULT_KEY:$canonicalName", modelClass)
    }

    @MainThread
    public open operator fun <T : ViewModel> get(key: String, modelClass: Class<T>): T {
    
        //ViewModelStore通过key获取ViewModel对象
        val viewModel = store[key]
        if (modelClass.isInstance(viewModel)) {
    
            (factory as? OnRequeryFactory)?.onRequery(viewModel)
            return viewModel as T
        } else {
    
            @Suppress("ControlFlowWithEmptyBody")
            if (viewModel != null) {
    
                // TODO: log a warning.
            }
        }
        val extras = MutableCreationExtras(defaultCreationExtras)
        extras[VIEW_MODEL_KEY] = key
        return try {
    
            //使用工厂模式创建ViewModel对象,Created and stored in ViewModelStore中
            factory.create(modelClass, extras)
        } catch (e: AbstractMethodError) {
    
            factory.create(modelClass)
        }.also {
     store.put(key, it) }
    }
    
    public open class NewInstanceFactory : Factory {
    
        override fun <T : ViewModel> create(modelClass: Class<T>): T {
    
            return try {
    
                modelClass.newInstance()
            } catch (e: InstantiationException) {
    
                throw RuntimeException("Cannot create an instance of $modelClass", e)
            } catch (e: IllegalAccessException) {
    
                throw RuntimeException("Cannot create an instance of $modelClass", e)
            }
        }

        public companion object {
    
            private var sInstance: NewInstanceFactory? = null
            @JvmStatic
            public val instance: NewInstanceFactory
                @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
                get() {
    
                    if (sInstance == null) {
    
                        sInstance = NewInstanceFactory()
                    }
                    return sInstance!!
                }

            private object ViewModelKeyImpl : Key<String>
            @JvmField
            val VIEW_MODEL_KEY: Key<String> = ViewModelKeyImpl
        }
    }
}

说明:

First call the constructor to createViewModelProvider对象,再调用get()方法获取ViewModel对象.

ComponentActivity类

public class ComponentActivity extends androidx.core.app.ComponentActivity implements
    ViewModelStoreOwner {
     

    //ViewModel存储容器
    private ViewModelStore mViewModelStore;
    //ViewModel的创建工厂
    private ViewModelProvider.Factory mDefaultFactory;

    public ComponentActivity() {
    
        //监听Activity生命周期
        getLifecycle().addObserver(new LifecycleEventObserver() {
    
            @Override
            public void onStateChanged(@NonNull LifecycleOwner source,
                                       @NonNull Lifecycle.Event event) {
    
                if (event == Lifecycle.Event.ON_DESTROY) {
    
                    //Activity在onDestroy时清理ViewModelStore
                    mContextAwareHelper.clearAvailableContext();                    
                    if (!isChangingConfigurations()) {
    
                        getViewModelStore().clear();
                    }
                }
            }
        });
    }

    @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.");
        }
        ensureViewModelStore();
        return mViewModelStore;
    }

    //创建ViewModelStore对象
    void ensureViewModelStore() {
    
        if (mViewModelStore == null) {
    
            NonConfigurationInstances nc =
                (NonConfigurationInstances) getLastNonConfigurationInstance();
            if (nc != null) {
    
                mViewModelStore = nc.viewModelStore;
            }
            if (mViewModelStore == null) {
    
                mViewModelStore = new ViewModelStore();
            }
        }
    }

    //屏幕旋转时调用
    @Override
    @Nullable
    public final Object onRetainNonConfigurationInstance() {
    
        Object custom = onRetainCustomNonConfigurationInstance();
        ViewModelStore viewModelStore = mViewModelStore;
        if (viewModelStore == null) {
    
            //恢复ViewModelStore对象
            NonConfigurationInstances nc =
                (NonConfigurationInstances) getLastNonConfigurationInstance();
            if (nc != null) {
    
                viewModelStore = nc.viewModelStore;
            }
        }

        if (viewModelStore == null && custom == null) {
    
            return null;
        }

        //保存ViewModelStore对象
        NonConfigurationInstances nci = new NonConfigurationInstances();
        nci.custom = custom;
        nci.viewModelStore = viewModelStore;
        return nci;
    }

    static final class NonConfigurationInstances {
    
        Object custom;
        ViewModelStore viewModelStore;
    }
}

说明:

ComponentActivity类实现了ViewModelStoreOwner接口并实现了getViewModelStore()方法,Activity在创建时生成ViewModelStore对象.

当ActivityWhen rotating the screen causes it to be destroyed,不仅会调用onSaveInstanceState()方法,还会调用onRetainNonConfigurationInstance()方法,Saved when the screen is rotatedViewModelStore对象.

by viewModels()

@MainThread
public inline fun <reified VM : ViewModel> ComponentActivity.viewModels(
    noinline factoryProducer: (() -> Factory)? = null
): Lazy<VM> {
    
    val factoryPromise = factoryProducer ?: {
    
        defaultViewModelProviderFactory
    }
    return ViewModelLazy(VM::class, {
     viewModelStore }, factoryPromise)
}
public class ViewModelLazy<VM : ViewModel> @JvmOverloads constructor(
    private val viewModelClass: KClass<VM>,
    private val storeProducer: () -> ViewModelStore,
    private val factoryProducer: () -> ViewModelProvider.Factory,
    private val extrasProducer: () -> CreationExtras = {
     CreationExtras.Empty }
) : Lazy<VM> {
    
    private var cached: VM? = null

    override val value: VM
        get() {
    
            val viewModel = cached
            return if (viewModel == null) {
    
                val factory = factoryProducer()
                val store = storeProducer()
                //最终也是通过 ViewModelProvider 创建 ViewModel 实例
                ViewModelProvider(
                    store,
                    factory,
                    extrasProducer()
                ).get(viewModelClass.java).also {
    
                    cached = it
                }
            } else {
    
                viewModel
            }
        }

    override fun isInitialized(): Boolean = cached != null
}

Data preservation phase

The data on the page can be defined in two categories:

  • 配置数据:窗口大小、主题资源、Multilingual characters, etc.
  • 非配置数据:用户信息、Audio and video playback information、异步任务等.

When device configuration changes,需要根据最新的配置重新读取新的数据,Therefore, this part of the data is meaningless after configuration changes,无需保存;Non-configuration data has nothing to do with device configuration,在重建Activity时会丢失,无法快速恢复页面数据,降低用户体验度.

ActivityThread#handleDestroyActivity#

public void handleDestroyActivity(ActivityClientRecord r, boolean finishing, int configChanges,
                                  boolean getNonConfigInstance, String reason) {
    
    performDestroyActivity(r, finishing, configChanges, getNonConfigInstance, reason);

    if (finishing) {
    
        ActivityClient.getInstance().activityDestroyed(r.token);
    }
}

ActivityThread#performDestroyActivity

void performDestroyActivity(ActivityClientRecord r, boolean finishing,
                            int configChanges, boolean getNonConfigInstance, String reason) {
    

    if (getNonConfigInstance) {
    
        try {
    
            //调用Activity#retainNonConfigurationInstances(),并存放在ActivityClientRecord
            r.lastNonConfigurationInstances = r.activity.retainNonConfigurationInstances();
        } 
    }
    //回调Activity#onDestroy()
    mInstrumentation.callActivityOnDestroy(r.activity);
}

Activity#retainNonConfigurationInstances()

NonConfigurationInstances retainNonConfigurationInstances() {
    
    Object activity = onRetainNonConfigurationInstance();
    //Indirect callbackComponentActivity#onRetainNonConfigurationInstance(),并返回NonConfigurationInstances对象
    HashMap<String, Object> children = onRetainNonConfigurationChildInstances();
    FragmentManagerNonConfig fragments = mFragments.retainNestedNonConfig();

    mFragments.doLoaderStart();
    mFragments.doLoaderStop(true);
    ArrayMap<String, LoaderManager> loaders = mFragments.retainLoaderNonConfig();

    if (activity == null && children == null && fragments == null && loaders == null
        && mVoiceInteractor == null) {
    
        return null;
    }

    NonConfigurationInstances nci = new NonConfigurationInstances();
    nci.activity = activity;
    nci.children = children;
    nci.fragments = fragments;
    nci.loaders = loaders;
    if (mVoiceInteractor != null) {
    
        mVoiceInteractor.retainInstance();
        nci.voiceInteractor = mVoiceInteractor;
    }
    //返回NonConfigurationInstances对象
    return nci;
}

Activity#onRetainNonConfigurationInstance()

//This method is handed over to the childActivity实现
public Object onRetainNonConfigurationInstance() {
    
    return null;
}

androidx.activity.ComponentActivity#onRetainNonConfigurationInstance()

public final Object onRetainNonConfigurationInstance() {
    
    //mViewModelStore为当前Activity的ViewModelStore
    ViewModelStore viewModelStore = mViewModelStore;

    //如果Activity没有调用getViewModelStore(),Well check oldActivity传递过来的数据
    if (viewModelStore == null) {
    
        NonConfigurationInstances nc =
            (NonConfigurationInstances) getLastNonConfigurationInstance();
        if (nc != null) {
    
            viewModelStore = nc.viewModelStore;
        }
    }

    //viewModelStore为null说明Activity和旧Activity没有ViewModel
    if (viewModelStore == null && custom == null) {
    
        return null;
    }

    NonConfigurationInstances nci = new NonConfigurationInstances();
    //换成ViewModelStore对象
    nci.viewModelStore = viewModelStore;
    //返回NonConfigurationInstances对象
    return nci;
}

数据恢复阶段

ActivityThread#handleRelaunchActivity()

public void handleRelaunchActivity(ActivityClientRecord tmp,
                                   PendingTransactionActions pendingActions) {
    
    ActivityClientRecord r = mActivities.get(tmp.token);
    r.activity.mConfigChangeFlags |= configChanges;
    r.mPreserveWindow = tmp.mPreserveWindow;
    r.activity.mChangingConfigurations = true;

    handleRelaunchActivityInner(r, configChanges, tmp.pendingResults, tmp.pendingIntents,
                                pendingActions, tmp.startsNotResumed, tmp.overrideConfig, "handleRelaunchActivity");
}

ActivityThread#handleRelaunchActivityInner()

private void handleRelaunchActivityInner(ActivityClientRecord r, int configChanges,         List<ResultInfo> pendingResults, List<ReferrerIntent> pendingIntents, PendingTransactionActions pendingActions, boolean startsNotResumed, Configuration overrideConfig, String reason) {
    
    //回调Activity#onPause()
    performPauseActivity(r, false, reason, null /* pendingActions */);
    //回调Activity#onStop()
    callActivityOnStop(r, true /* saveState */, reason);
	//获取Activityof non-configuration data
    handleDestroyActivity(r, false, configChanges, true, reason);
	//间接在Activity#attach()pass oldActivity的数据
    handleLaunchActivity(r, pendingActions, customIntent);
}

ActivityThread#handleLaunchActivity

public Activity handleLaunchActivity(ActivityClientRecord r,
                                     PendingTransactionActions pendingActions, 
                                     Intent customIntent) {
    

    final Activity a = performLaunchActivity(r, customIntent);
    return a;
}

ActivityThread#performLaunchActivity()

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
    
    //创建新的Activity 
    Activity activity = mInstrumentation.newActivity(cl, component.getClassName(), r.intent);
    //Create Fire GetApplication实例
    Application app = r.packageInfo.makeApplication(false, mInstrumentation);
    //传递lastNonConfigurationInstances数据
    activity.attach(appContext, this, getInstrumentation(), r.token,
                    r.ident, app, r.intent, r.activityInfo, title, r.parent,
                    r.embeddedID, r.lastNonConfigurationInstances, config,
                    r.referrer, r.voiceInteractor, window, r.configCallback,
                    r.assistToken, r.shareableActivityToken);
    //清空临时变量
    r.lastNonConfigurationInstances = null;
    return activity;
}

Activity#attach()

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,
                  IBinder shareableActivityToken) {
    
    	//将旧Activityof non-configuration data is saved
        mLastNonConfigurationInstances = lastNonConfigurationInstances;
}

ComponentActivity#getViewModelStore()

获取ViewModelStore

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.");
    }
    ensureViewModelStore();
    return mViewModelStore;
}

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();
        }
    }
}
原网站

版权声明
本文为[xiangxiongfly915]所创,转载请带上原文链接,感谢
https://chowdera.com/2022/266/202209230813475557.html

随机推荐