简体   繁体   English

ViewModelProvider.Factory 和 ViewModelProvider.NewInstanceFactory 有什么区别?

[英]What are the differences between ViewModelProvider.Factory and ViewModelProvider.NewInstanceFactory?

I'm currently transforming my project architecture from MVP to MVVM.我目前正在将我的项目架构从 MVP 转换为 MVVM。 When I'm working on it, I find something made me confused:当我处理它时,我发现一些让我感到困惑的事情:

In ScheduleViewModelFactory.kt of project iosched , the factory implements ViewModelProvider.Factory:ScheduleViewModelFactory.kt项目iosched ,工厂器具ViewModelProvider.Factory:

class ScheduleViewModelFactory(
    private val userEventRepository:DefaultSessionAndUserEventRepository
) : ViewModelProvider.Factory {

    @Suppress("UNCHECKED_CAST")
    override fun <T : ViewModel> create(modelClass: Class<T>): T {
        if (modelClass.isAssignableFrom(ScheduleViewModel::class.java)) {
            return ScheduleViewModel(LoadUserSessionsByDayUseCase(userEventRepository)) as T
        }
        throw IllegalArgumentException("Unknown ViewModel class")
    }
}

In DetailViewModelFactory.java of project Sunshine from codelab , the factory extends ViewModelProvider.NewInstanceFactory:DetailViewModelFactory.java项目阳光从代码实验室,工厂扩展ViewModelProvider.NewInstanceFactory:

public class DetailViewModelFactory extends ViewModelProvider.NewInstanceFactory {

    private final SunshineRepository mRepository;
    private final Date mDate;

    public DetailViewModelFactory(SunshineRepository repository, Date date) {
        this.mRepository = repository;
        this.mDate = date;
    }

    @Override
    public <T extends ViewModel> T create(Class<T> modelClass) {
        //noinspection unchecked
        return (T) new DetailActivityViewModel(mRepository, mDate);
    }
}

I would like to know:我想知道:

  1. What are the differences between ViewModelProvider.Factory and ViewModelProvider.NewInstanceFactory ? ViewModelProvider.FactoryViewModelProvider.NewInstanceFactory之间有什么区别?
  2. Why they are being used like the codes mentioned above?为什么它们像上面提到的代码一样被使用?
  3. What is the best practice/scenario to use each of them?使用它们的最佳实践/场景是什么?

What are the differences between ViewModelProvider.Factory and ViewModelProvider.NewInstanceFactory? ViewModelProvider.Factory 和 ViewModelProvider.NewInstanceFactory 有什么区别?

Why they are being used like the codes mentioned above?为什么它们像上面提到的代码一样被使用?

Basing on ViewModelProvider documentation:基于ViewModelProvider文档:

public class ViewModelProvider {
    /**
     * Implementations of {@code Factory} interface are responsible to instantiate ViewModels.
     */
    public interface Factory {
        @NonNull
        <T extends ViewModel> T create(@NonNull Class<T> modelClass);
    (...)


    /**
     * Simple factory, which calls empty constructor on the given class.
     */
    public static class NewInstanceFactory implements Factory {

        @SuppressWarnings("ClassNewInstance")
        @NonNull
        @Override
        public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
            //noinspection TryWithIdenticalCatches
            try {
                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);
            }
        }
    }
    (...)
}

and taking geeksforgeeks description of newInstance() into consideration:并考虑geeksforgeeksnewInstance()描述:

In general, new operator is used to create objects, but if we want to decide type of object to be created at runtime, there is no way we can use new operator.一般情况下,new操作符是用来创建对象的,但是如果我们想在运行时决定要创建的对象的类型,就没有办法使用new操作符了。 In this case, we have to use newInstance() method.在这种情况下,我们必须使用 newInstance() 方法。

I assume the NewInstanceFactory is an implementation of the Factory , which can be used when we want to create ViewModels of different types.我假设NewInstanceFactoryFactory的实现,当我们想要创建不同类型的 ViewModel 时可以使用它。


On the other hand, in google's android-architecture/todoapp there is:另一方面,在谷歌的android-architecture/todoapp 中有:

public class ViewModelFactory extends ViewModelProvider.NewInstanceFactory {
    (...)
    @Override
    public <T extends ViewModel> T create(Class<T> modelClass) {
        if (modelClass.isAssignableFrom(StatisticsViewModel.class)) {
            //noinspection unchecked
            return (T) new StatisticsViewModel(mApplication, mTasksRepository);
        } else if (modelClass.isAssignableFrom(TaskDetailViewModel.class)) {
            //noinspection unchecked
            return (T) new TaskDetailViewModel(mApplication, mTasksRepository);
        } else if (modelClass.isAssignableFrom(AddEditTaskViewModel.class)) {
            //noinspection unchecked
            return (T) new AddEditTaskViewModel(mApplication, mTasksRepository);
        } else if (modelClass.isAssignableFrom(TasksViewModel.class)) {
            //noinspection unchecked
            return (T) new TasksViewModel(mApplication, mTasksRepository);
        }
        throw new IllegalArgumentException("Unknown ViewModel class: " + modelClass.getName());
    }
}

They are using the NewInstanceFactory , but are overriding the create method!他们正在使用NewInstanceFactory ,但覆盖了create方法! To my understanding, if we override it, there's no difference from using a regular Factory .据我了解,如果我们覆盖它,则与使用常规Factory没有区别。

ViewModelProvider.Factory is responsible to create your instance of ViewModel. ViewModelProvider.Factory 负责创建您的 ViewModel 实例。

If your ViewModel have dependencies and you want to test your ViewModel then you should create your own ViewModelProvider.Factory and passed dependency through ViewModel constructor and give value to the ViewModelProvider.Factory instance.如果您的 ViewModel 有依赖项并且您想测试您的 ViewModel,那么您应该创建自己的 ViewModelProvider.Factory 并通过 ViewModel 构造函数传递依赖项,并为 ViewModelProvider.Factory 实例赋值。

When to use ViewModelProvider.Factory?何时使用 ViewModelProvider.Factory?

If your ViewModel have dependencies then you should pass this dependencies through the constructor (It is the best way to pass your dependencies), so you can mock that dependencies and test your ViewModel.如果您的 ViewModel 有依赖项,那么您应该通过构造函数传递这些依赖项(这是传递您的依赖项的最佳方式),这样您就可以模拟该依赖项并测试您的 ViewModel。

When not to use ViewModelProvider.Factory何时不使用 ViewModelProvider.Factory

If your ViewModel have no dependencies then you will not require to create your own ViewModelProvider.Factory.如果您的 ViewModel 没有依赖项,那么您将不需要创建自己的 ViewModelProvider.Factory。 The default implementation is enough to create ViewModel for you.默认实现足以为您创建 ViewModel。

Please go through this blog for details.请浏览此博客了解详情。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM