ViewModel源码分析

ViewModel创建

ViewModelProvider(this).get(CustomModel::class.java)
  • 点进源码查看ViewModelProvider实现
// 实际上调用的方法是ViewModelProvider(activity.getViewModelStore, factory)
public ViewModelProvider(@NonNull ViewModelStoreOwner owner) {
	
	// 对传入的参数进行处理	 owner.getViewModelStore(),  factory
    this(owner.getViewModelStore(), owner instanceof HasDefaultViewModelProviderFactory
            ? ((HasDefaultViewModelProviderFactory) owner).getDefaultViewModelProviderFactory()
            : NewInstanceFactory.getInstance());
}

owner.getViewModelStore()

// ComponentActivity获取ViewModelStoreOwner(activity/fragment)的viewModelStore
@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.activity中获取ViewModel
        NonConfigurationInstances nc =
                (NonConfigurationInstances) getLastNonConfigurationInstance();
        if (nc != null) {
            // Restore the ViewModelStore from NonConfigurationInstances
            mViewModelStore = nc.viewModelStore;
        }
        if (mViewModelStore == null) {
            // 如果保存的状态为空且mViewModelStore为空,则直接创建ViewModelStore
            mViewModelStore = new ViewModelStore();
        }
    }
    // mViewModelStore不为空直接返回    
    return mViewModelStore;
}
  • 在上面方法中,我们注意到当ViewModelStore为null时,需要从NonConfigurationInstances中获取viewModelStore, 所以我们在点进去看一下NonConfigurationInstances到底做了什么

NonConfigurationInstances

  • Activity状态保留我们一般都是通过onSaveInstanceState保存数据,还原时使用onRestoreInstanceState,但是这种方法保存数据具有一定的局限性:数据不可过大,数据需要序列化。Android还提供了另外一套保存和恢复机制,getLastNonConfigurationInstance和o’nRetainNonConfigurationInstance, 这两个方法可以通过一个包含状态的object对象来传递信息:
/**
 * ComponentActivity的NonConfigurationInstances
 */
static final class NonConfigurationInstances {
    Object custom;  // 自定义内容
    ViewModelStore viewModelStore;
}

/**
 * Activity中的NonConfigurationInstances
 */
static final class NonConfigurationInstances {
    Object activity;
    HashMap<String, Object> children;
    FragmentManagerNonConfig fragments;
    ArrayMap<String, LoaderManager> loaders;
    VoiceInteractor voiceInteractor;
}

/**
 * ComponentActivity onRetainNonConfigurationInstance重写Activity中的方法,当前ViewModelStoreOwner销毁保存信息
 */
@Override
@Nullable
public final Object onRetainNonConfigurationInstance() {
    Object custom = onRetainCustomNonConfigurationInstance();
    ViewModelStore viewModelStore = mViewModelStore;
    if (viewModelStore == null) {
        NonConfigurationInstances nc =
                (NonConfigurationInstances) getLastNonConfigurationInstance();
        if (nc != null) {
            // 保存Activity中的NonConfigurationInstances.activity的ViewModel 
            viewModelStore = nc.viewModelStore;
        }
    }
    if (viewModelStore == null && custom == null) {
        return null;
    }
    NonConfigurationInstances nci = new NonConfigurationInstances();
    nci.custom = custom;
    nci.viewModelStore = viewModelStore;
    return nci;
}

/**
 * 状态恢复, 返回Activity中的mLastNonConfigurationInstances.activity
 */
public Object getLastNonConfigurationInstance() {
    return mLastNonConfigurationInstances != null
            ? mLastNonConfigurationInstances.activity : null;
}
  • 从上面代码可以看出,activity/fragment 销毁和重建保存和恢复的时ViewModelStore,那么ViewModel哪里去了?在ViewModelStore中通过HashMap存储者ViewModel

ViewModelStore(ViewModel存储容器)

// ViewModelStore
public class ViewModelStore {

    // 通过HashMap存储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());
    }

    // 在Activity和Fragment的onDestory方法中,会执行clear方法,执行所有ViewModel的onCleared的方法,清空Map集合里面的ViewModel
    
    public final void clear() {
        for (ViewModel vm : mMap.values()) {
            vm.clear();
        }
        mMap.clear();
    }
}

Factory

  • ViewModelProvider的第二个参数是factory, Factory存在两个实现类:ViewModelProvider.AndroidViewModelFactory.getInstance(application);
    或者 NewInstanceFactory.getInstance(),具体代码如下
NewInstanceFactory
public static class NewInstanceFactory implements Factory {
    private static NewInstanceFactory sInstance;
    /**
     * Retrieve a singleton instance of NewInstanceFactory.
     *
     * @return A valid {@link NewInstanceFactory}
     */
    @NonNull
    static NewInstanceFactory getInstance() {
        if (sInstance == null) {
            sInstance = new NewInstanceFactory();
        }
        return sInstance;
    }
    @SuppressWarnings("ClassNewInstance")
    @NonNull
    @Override
    public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
        //noinspection TryWithIdenticalCatches
        try {
        
        //  返回ViewModel实例
        
            return modelClass.newInstance();
        } catch (InstantiationException e) {
            throw new RuntimeException("Cannot create an instance of " + modelClass, e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException("Cannot create an instance of " + modelClass, e);
        }
    }
}

ANdroidViewModelFactory(NewInstanceFactory的直接子类)
public static class AndroidViewModelFactory extends ViewModelProvider.NewInstanceFactory {
    private static AndroidViewModelFactory sInstance;
    /**
     * Retrieve a singleton instance of AndroidViewModelFactory.
     *
     * @param application an application to pass in {@link AndroidViewModel}
     * @return A valid {@link AndroidViewModelFactory}
     */
    @NonNull
    public static AndroidViewModelFactory getInstance(@NonNull Application application) {
        if (sInstance == null) {
            sInstance = new AndroidViewModelFactory(application);
        }
        return sInstance;
    }
    private Application mApplication;
    /**
     * Creates a {@code AndroidViewModelFactory}
     *
     * @param application an application to pass in {@link AndroidViewModel}
     */
    public AndroidViewModelFactory(@NonNull Application application) {
        mApplication = application;
    }


    @NonNull
    @Override
    public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
        if (AndroidViewModel.class.isAssignableFrom(modelClass)) {
            //noinspection TryWithIdenticalCatches
            try {
            // 通过get方法传入的ViewModel返回带有applicationContext的ViewModel
                return modelClass.getConstructor(Application.class).newInstance(mApplication);
            } catch (NoSuchMethodException e) {
                throw new RuntimeException("Cannot create an instance of " + modelClass, e);
            } catch (IllegalAccessException e) {
                throw new RuntimeException("Cannot create an instance of " + modelClass, e);
            } catch (InstantiationException e) {
                throw new RuntimeException("Cannot create an instance of " + modelClass, e);
            } catch (InvocationTargetException e) {
                throw new RuntimeException("Cannot create an instance of " + modelClass, e);
            }
        }
        return super.create(modelClass);
    }
}

通过get方法生成ViewModel实例

@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");
    }

//  生成ViewModelStore中HashMap的key

    return get(DEFAULT_KEY + ":" + canonicalName, modelClass);
}

@NonNull
@MainThread
public <T extends ViewModel> T get(@NonNull String key, @NonNull Class<T> modelClass) {

    // 通过Key产找到ViewModel
    
    ViewModel viewModel = mViewModelStore.get(key);

    // 如果获取的ViewModel和传入的ViewModel的Class的对象相同,则直接返回给ViewModel

    if (modelClass.isInstance(viewModel)) {
        if (mFactory instanceof OnRequeryFactory) {
            ((OnRequeryFactory) mFactory).onRequery(viewModel);
        }
        return (T) viewModel;
    } else {
        //noinspection StatementWithEmptyBody
        if (viewModel != null) {
            // TODO: log a warning.
        }
    }

    // 通过工厂生产一个ViewModel实例(可能带有applicationcontext)
    
    if (mFactory instanceof KeyedFactory) {
        viewModel = ((KeyedFactory) (mFactory)).create(key, modelClass);
    } else {
        viewModel = (mFactory).create(modelClass);
    }
    mViewModelStore.put(key, viewModel);
    return (T) viewModel;
}

ViewModel源码

abstract class ViewModel

    // ViewModel通过HashMap存储CoroutineScope对象
    
    private final Map<String, Object> mBagOfTags = new HashMap<>();

    // ViewModel被销毁时内部执行clear()方法,
    @MainThread
    final void clear() {
        mCleared = true;
        if (mBagOfTags != null) {
            synchronized (mBagOfTags) {
                for (Object value : mBagOfTags.values()) {
                    // 取消viewModelScope作用域的协程
                    closeWithRuntimeException(value);
                }
            }
        }
        onCleared();
    }

// 取消CoroutineScope
    private static void closeWithRuntimeException(Object obj) {
        if (obj instanceof Closeable) {
            try {
                ((Closeable) obj).close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }


    // 如果JOB_KEY已存在且对应的协程作用域不为空则返回对象,否则创建新的协程作用域,并设置JOB_KEY
    @SuppressWarnings("unchecked")
    <T> T setTagIfAbsent(String key, T newValue) {
        T previous;
        synchronized (mBagOfTags) {
            previous = (T) mBagOfTags.get(key);
            if (previous == null) {
                mBagOfTags.put(key, newValue);
            }
        }
        T result = previous == null ? newValue : previous;
        if (mCleared) {
            closeWithRuntimeException(result);
        }
        return result;
    }

    // 通过JOB_KEY从HashMap中返回相应的协程作用域
    @SuppressWarnings({"TypeParameterUnusedInFormals", "unchecked"})
    <T> T getTag(String key) {
        synchronized (mBagOfTags) {
            return (T) mBagOfTags.get(key);
        }
    }

}

AndroidViewModel

public class AndroidViewModel extends ViewModel {
    @SuppressLint("StaticFieldLeak")
    private Application mApplication;


    public AndroidViewModel(@NonNull Application application) {
        mApplication = application;
    }


    // 返回application
    @SuppressWarnings({"TypeParameterUnusedInFormals", "unchecked"})
    @NonNull
    public <T extends Application> T getApplication() {
        return (T) mApplication;
    }
}

©️2020 CSDN 皮肤主题: 技术黑板 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值