До сих пор я следовал руководству для разработчиков Android по компонентам архитектуры и, конечно, проблема была в том, что их примеры не могли работать с заводской установкой по умолчанию ' без исключения нулевого аргумента '.Я придерживался некоторой логики репозитория примеров Google, а также довольно большого количества предложений StackOverflow, а также блогов и учебных пособий.Но я все еще получаю ту же ошибку.
Теперь, Я думаю, что я обнаружил проблему , и похоже, что мой ViewModelFactory по-прежнему равен нулю, так что ViewModelProvider заменяет его на значение по умолчаниюФабрика, которая, конечно, ожидает конструктор с нулевым аргументом.Но я до сих пор не понимаю, что именно с кодом не так.
Так что у меня в основном есть ViewModelFactory
public class ViewModelFactory implements ViewModelProvider.Factory {
private final Map<Class<? extends CustomViewModel>, Provider<CustomViewModel>> viewModels;
@Inject
public ViewModelFactory(Map<Class<? extends CustomViewModel>, Provider<CustomViewModel>> viewModels) {
this.viewModels = viewModels;
}
@SuppressWarnings("unchecked")
@Override
public <T extends ViewModel> T create(Class<T> modelClass) {
Provider<? extends CustomViewModel> viewModelProvider = viewModels.get(modelClass);
if (viewModelProvider == null) {
for (Map.Entry<Class<? extends CustomViewModel>, Provider<CustomViewModel>> entry : viewModels.entrySet()) {
if (modelClass.isAssignableFrom(entry.getKey())) {
viewModelProvider = entry.getValue();
break;
}
}
}
if (viewModelProvider == null) {
throw new IllegalArgumentException("unknown model class " + modelClass);
}
try {
return (T) viewModelProvider.get();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
и AppComponent
@Singleton
@Component(modules = {AndroidSupportInjectionModule.class, ViewModelModule.class})
public interface AppComponent {
@Component.Builder
interface Builder {
@BindsInstance
Builder application(App application);
AppComponent build();
}
void inject(App application);
}
А затем ViewModelModule
@Module
public abstract class ViewModelModule {
@Binds
abstract ViewModelProvider.Factory bindViewModelFactory(ViewModelFactory viewModelFactory);
@Binds
@IntoMap
@ViewModelKey(HourlyViewModel.class)
abstract ViewModel bindHourlyViewModel(HourlyViewModel hourlyViewModel);
}
И ViewModelKey
@Documented
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@MapKey
@interface ViewModelKey {
Class<? extends CustomViewModel> value();
}
И ViewModel
public class HourlyViewModel extends CustomViewModel {
private LiveData<HourlyData> hourlyData;
private MainRepository mainRepo;
@Inject
public HourlyViewModel(HourlyRepository mainRepo) {
this.mainRepo = mainRepo;
}
@Override
public void init(int id, long start, long stop) {
super.init(id, start, stop);
// some logic
}
}
И бонус CustomViewModel
public class CustomViewModel extends ViewModel {
public OpenDataApi api;
public int id;
public long start;
public long stop;
/**
*
* @param id
* @param start
* @param stop
*/
public void init(int id, long start, long stop) {
api = OpenDataApi.getRetrofitInstance().create(OpenDataApi.class);
this.id = id;
this.start = start;
this.stop = stop;
}
}
Мое приложение
public class App extends Application {
@Override
public void onCreate() {
super.onCreate();
DaggerAppComponent
.builder()
.application(this)
.build()
.inject(this);
AndroidThreeTen.init(this);
}
}
И как я пытаюсь вызвать ViewModel во фрагменте
public class FragmentHourly extends Fragment {
@Inject
ViewModelFactory viewModelFactory;
private HourlyViewModel viewModel;
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
viewModel = ViewModelProviders.of(this, viewModelFactory).get(HourlyViewModel.class);
}
}
Что именно мне здесь не хватает?Моя реализация неверна или чего-то не хватает?
Приветствия и спасибо за помощь