Каковы различия между ViewModelProvider.Factory и ViewModelProvider.NewInstanceFactory? - PullRequest
0 голосов
/ 23 сентября 2018

В настоящее время я преобразовываю архитектуру своего проекта из MVP в MVVM.Когда я работаю над этим, я обнаружил, что что-то меня смутило:

В 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")
    }
}

В DetailViewModelFactory.java проекта Sunshine из codelab завод расширяет 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);
    }
}

Я хотел бы знать:

  1. В чем различия между ViewModelProvider.Factory и ViewModelProvider.NewInstanceFactory ?
  2. Почему они используются как коды, упомянутые выше?
  3. Каков наилучший метод / сценарий использования каждого из них?

1 Ответ

0 голосов
/ 13 ноября 2018

В чем различия между ViewModelProvider.Factory и ViewModelProvider.NewInstanceFactory?

Почему они используются как коды, упомянутые выше?

На основе 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);
            }
        }
    }
    (...)
}

и с учетом geeksforgeeks описание newInstance():

В общем, для создания используется новый операторобъекты, но если мы хотим определить тип объекта, который будет создан во время выполнения, мы не сможем использовать оператор new.В этом случае мы должны использовать метод newInstance ().

Я предполагаю, что NewInstanceFactory - это реализация Factory, которую можно использовать, когда мы хотим создать ViewModel разных типов.,


С другой стороны, в google's android-архитектура / 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());
    }
}

Они используют NewInstanceFactory, но переопределение create метода! Насколько я понимаю, если мы переопределим его, нет никакой разницы от использования обычного Factory.

...