ViewModel не имеет конструктора с нулевым аргументом hilt Java

#java #android #viewmodel #android-lifecycle #dagger-hilt

#java #Android #viewmodel #android-жизненный цикл #кинжал-рукоять

Вопрос:

Я использую hilt и пытаюсь импортировать мой SessionManager в свой AuthViewModel класс.

Когда я просматриваю документацию Google по hilt с ViewModel. Мы видим, что они могут вводить ExampleRepository repository в конструктор указанные ExampleViewModel

 public class ExampleViewModel extends ViewModel {

  private final ExampleRepository repository;
  private final SavedStateHandle savedStateHandle;

  @ViewModelInject
  ExampleViewModel(
      ExampleRepository repository,
      @Assisted SavedStateHandle savedStateHandle)
    {
    this.repository = repository;
    this.savedStateHandle = savedStateHandle;
  }
  ...
}
 

и

   @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    exampleViewModel = new ViewModelProvider(this).get(ExampleViewModel.class);
  }
 

Всякий раз, когда я пытаюсь сделать это со своим проектом, я продолжаю получать ошибку.

 E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.atchat.donation, PID: 11005
    java.lang.RuntimeException: Cannot create an instance of class com.atchat.donation.ui.auth.AuthViewModel
        at androidx.lifecycle.ViewModelProvider$NewInstanceFactory.create(ViewModelProvider.java:221)
        at androidx.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.java:278)
        at androidx.lifecycle.SavedStateViewModelFactory.create(SavedStateViewModelFactory.java:106)
        at androidx.hilt.lifecycle.HiltViewModelFactory.create(HiltViewModelFactory.java:74)
        at androidx.lifecycle.AbstractSavedStateViewModelFactory.create(AbstractSavedStateViewModelFactory.java:69)
        at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:185)
        at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:150)
        at com.atchat.donation.ui.auth.LoginFragment.onViewCreated(LoginFragment.java:97)
        at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:332)
        at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1199)
        at androidx.fragment.app.FragmentManager.addAddedFragments(FragmentManager.java:2236)
        at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:2009)
        at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:1965)
        at androidx.fragment.app.FragmentManager.execPendingActions(FragmentManager.java:1861)
        at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:2641)
        at androidx.fragment.app.FragmentManager.dispatchActivityCreated(FragmentManager.java:2589)
        at androidx.fragment.app.Fragment.performActivityCreated(Fragment.java:2723)
        at androidx.fragment.app.FragmentStateManager.activityCreated(FragmentStateManager.java:346)
        at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1200)
        at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1368)
        at androidx.fragment.app.FragmentManager.moveFragmentToExpectedState(FragmentManager.java:1446)
        at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1509)
        at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:2637)
        at androidx.fragment.app.FragmentManager.dispatchActivityCreated(FragmentManager.java:2589)
        at androidx.fragment.app.FragmentController.dispatchActivityCreated(FragmentController.java:247)
        at androidx.fragment.app.FragmentActivity.onStart(FragmentActivity.java:541)
        at androidx.appcompat.app.AppCompatActivity.onStart(AppCompatActivity.java:210)
        at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1425)
        at android.app.Activity.performStart(Activity.java:7825)
        at android.app.ActivityThread.handleStartActivity(ActivityThread.java:3294)
        at android.app.servertransaction.TransactionExecutor.performLifecycleSequence(TransactionExecutor.java:221)
        at android.app.servertransaction.TransactionExecutor.cycleToPath(TransactionExecutor.java:201)
        at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:173)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:97)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016)
        at android.os.Handler.dispatchMessage(Handler.java:107)
        at android.os.Looper.loop(Looper.java:214)
        at android.app.ActivityThread.main(ActivityThread.java:7356)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
     Caused by: java.lang.InstantiationException: java.lang.Class<com.atchat.donation.ui.auth.AuthViewModel> has no zero argument constructor
        at java.lang.Class.newInstance(Native Method)
        at androidx.lifecycle.ViewModelProvider$NewInstanceFactory.create(ViewModelProvider.java:219)
        at androidx.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.java:278) 
        at androidx.lifecycle.SavedStateViewModelFactory.create(SavedStateViewModelFactory.java:106) 
        at androidx.hilt.lifecycle.HiltViewModelFactory.create(HiltViewModelFactory.java:74) 
        at androidx.lifecycle.AbstractSavedStateViewModelFactory.create(AbstractSavedStateViewModelFactory.java:69) 
        at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:185) 
        at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:150) 
        at com.atchat.donation.ui.auth.LoginFragment.onViewCreated(LoginFragment.java:97) 
        at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:332) 
        at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1199) 
        at androidx.fragment.app.FragmentManager.addAddedFragments(FragmentManager.java:2236) 
        at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:2009) 
        at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:1965) 
        at androidx.fragment.app.FragmentManager.execPendingActions(FragmentManager.java:1861) 
        at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:2641) 
        at androidx.fragment.app.FragmentManager.dispatchActivityCreated(FragmentManager.java:2589) 
        at androidx.fragment.app.Fragment.performActivityCreated(Fragment.java:2723) 
        at androidx.fragment.app.FragmentStateManager.activityCreated(FragmentStateManager.java:346) 
        at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1200) 
        at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1368) 
        at androidx.fragment.app.FragmentManager.moveFragmentToExpectedState(FragmentManager.java:1446) 
        at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1509) 
        at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:2637) 
        at androidx.fragment.app.FragmentManager.dispatchActivityCreated(FragmentManager.java:2589) 
        at androidx.fragment.app.FragmentController.dispatchActivityCreated(FragmentController.java:247) 
        at androidx.fragment.app.FragmentActivity.onStart(FragmentActivity.java:541) 
        at androidx.appcompat.app.AppCompatActivity.onStart(AppCompatActivity.java:210) 
        at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1425) 
        at android.app.Activity.performStart(Activity.java:7825) 
        at android.app.ActivityThread.handleStartActivity(ActivityThread.java:3294) 
        at android.app.servertransaction.TransactionExecutor.performLifecycleSequence(TransactionExecutor.java:221) 
        at android.app.servertransaction.TransactionExecutor.cycleToPath(TransactionExecutor.java:201) 
        at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:173) 
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:97) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016) 
        at android.os.Handler.dispatchMessage(Handler.java:107) 
        at android.os.Looper.loop(Looper.java:214) 
        at android.app.ActivityThread.main(ActivityThread.java:7356) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930) 
I/Process: Sending signal. PID: 11005 SIG: 9
 

AuthViewModel

 public class AuthViewModel extends ViewModel {

    private static final String TAG = "AuthViewModel";
    private final SessionManager sessionManager;

    @ViewModelInject
    public AuthViewModel(SessionManager sessionManager, @Assisted SavedStateHandle savedStateHandle){
        this.sessionManager = sessionManager;
    }
...
}
 

AppModule

 @Module()
@InstallIn(SingletonComponent.class)
public class AppModule {

    @Provides
    public static SessionManager provideSessionManager(@ApplicationContext Context context, AccountRestService accountRestService){
        return new SessionManager(accountRestService, context);
    }
...
}
 

LoginFragment

 @AndroidEntryPoint
public class LoginFragment extends Fragment implements View.OnClickListener {

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        viewModel = new ViewModelProvider(this).get(AuthViewModel.class);
        subscribeObservers();
        attemptSilentLogin();
    }
...
}
 

build.gradle (модуль)

 apply plugin: 'dagger.hilt.android.plugin'

dependencies {
    //Hilt
    implementation 'com.google.dagger:hilt-android:2.30-alpha'
    implementation 'androidx.hilt:hilt-lifecycle-viewmodel:1.0.0-alpha02'
    annotationProcessor 'com.google.dagger:hilt-android-compiler:2.30-alpha'
...
}
 

build.gradle (проект)

 dependencies {
    classpath 'com.android.tools.build:gradle:4.1.1'
    classpath 'com.google.dagger:hilt-android-gradle-plugin:2.30-alpha'
}
 

Комментарии:

1. Можете ли вы включить всю трассировку стека (а не только первую строку)?

2. @ianhanniballake Я включил полную трассировку стека

Ответ №1:

Я тоже столкнулся с этой ошибкой, я пропустил то, что забыл добавить @AndroidEntryPoint MyFragment .

Поэтому обязательно добавьте все необходимые аннотации.

Ответ №2:

Ваше сообщение об ошибке показывает, что HiltViewModelFactory у него нет привязки для вашего конкретного AuthViewModel . Это не потому, что вы не включили дополнительное annotationProcessor , необходимое специально для интеграции Hilt и Jetpack — именно этот дополнительный androidx.hilt:hilt-compiler процессор аннотаций отвечает за чтение @ViewModelInject и генерацию правильных привязок Hilt.

 dependencies {
    // Hilt
    implementation 'com.google.dagger:hilt-android:2.30-alpha'
    annotationProcessor 'com.google.dagger:hilt-android-compiler:2.30-alpha'

    // Hilt Jetpack Integrations
    implementation 'androidx.hilt:hilt-lifecycle-viewmodel:1.0.0-alpha02'
    annotationProcessor 'androidx.hilt:hilt-compiler:1.0.0-alpha02'
...
}
 

Комментарии:

1. Я пропустил это в документах, но я также забыл добавить @AndroidEntryPoint в свою активность (которая, похоже, выдает идентичную ошибку).

2. Также: такая же ошибка может появиться, если @HiltViewModel аннотация отсутствует для самого класса ViewModel

Ответ №3:

Я использую Hilt в Kotlin, я получил ту же ошибку: "Cannot instantiate viewmodel ... has no zero arguments constructor"
Я уже вставил все аннотации: @HiltAndroidApp , @AndroidEntryPoint
Но я пропустил одно: @HiltViewModel после вставки этого поверх моей viewmodel все ошибки исчезли.

 @HiltViewModel //I missed this annotation
class LoginViewModel @Inject constructor(
    private val loginUseCase: LoginUseCase
) : ViewModel() {

}