Fixed
Status Update
Comments
da...@google.com <da...@google.com> #2
This is fixed internally and will be available in alpha02
sp...@gmail.com <sp...@gmail.com> #3
I've modified the build.gradle file (of the attached "MyAppplication" project) to the latest iteration (alpha2) to test the changes. When I pass through the same flow twice (shown in attached screen recording) I get an exception (listed below). Should I initiate a new issue for it?
--------- beginning of crash
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.myapplication, PID: 3799
java.util.NoSuchElementException
at java.util.ArrayDeque.removeLast(ArrayDeque.java:274)
at androidx.navigation.fragment.FragmentNavigator.popBackStack(FragmentNavigator.java:87)
at androidx.navigation.NavController.popBackStack(NavController.java:280)
at androidx.navigation.NavController.navigate(NavController.java:642)
at androidx.navigation.NavController.navigate(NavController.java:592)
at androidx.navigation.Navigation$1.onClick(Navigation.java:118)
at android.view.View.performClick(View.java:6294)
at android.view.View$PerformClick.run(View.java:24770)
at android.os.Handler.handleCallback(Handler.java:790)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6494)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
--------- beginning of crash
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.myapplication, PID: 3799
java.util.NoSuchElementException
at java.util.ArrayDeque.removeLast(ArrayDeque.java:274)
at androidx.navigation.fragment.FragmentNavigator.popBackStack(FragmentNavigator.java:87)
at androidx.navigation.NavController.popBackStack(NavController.java:280)
at androidx.navigation.NavController.navigate(NavController.java:642)
at androidx.navigation.NavController.navigate(NavController.java:592)
at androidx.navigation.Navigation$1.onClick(Navigation.java:118)
at android.view.View.performClick(View.java:6294)
at android.view.View$PerformClick.run(View.java:24770)
at android.os.Handler.handleCallback(Handler.java:790)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6494)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
sp...@gmail.com <sp...@gmail.com> #4
The alternative paths shown in the attached recordings also lead to the aforementioned exception.
sp...@gmail.com <sp...@gmail.com> #5
sp...@gmail.com <sp...@gmail.com> #6
sorry copied the wrong line sentencesViewModel = new ViewModelProvider(getStoreOwner(), getDefaultViewModelProviderFactory()).get(SentencesViewModel.class);
da...@google.com <da...@google.com> #7
Is that ViewModel in another Gradle module? Make sure you apply the androidx.hilt-compiler
too all the those modules where you have your @InjectViewModel
. Do you notice any other difference of that SentencesViewModel? If you can share an app that reproduces the issue that would be great.
sp...@gmail.com <sp...@gmail.com> #8
no its not in another module, the view model is this (removed some stuff for brevity)
private final SentenceRepository sentenceRepository;
private final GroupRepository groupRepository;
@ViewModelInject
SentencesViewModel(SentenceRepository sentenceRepository, GroupRepository groupRepository, @Clicks int clicks, @SentenceTypeAndDescription String[] cardArgs){
this.sentenceRepository = sentenceRepository;
this.groupRepository = groupRepository;
}
the view model is built by a component
@Component(dependencies = SentenceViewModelDependencies.class)
public interface SentenceViewModelComponent {
void inject(CardHolderFragment cardHolderFragment);
@Component.Builder
interface Builder {
Builder context(@BindsInstance Context context);
Builder appDependencies(SentenceViewModelDependencies sentenceViewModelDependencies);
SentenceViewModelComponent build();
}
}
the component needs
@EntryPoint
@InstallIn(ApplicationComponent.class)
public interface SentenceViewModelDependencies {
@SentenceTypeAndDescription String[] sentenceTypeAndDescription();
}
and the view model needs
@Module
@InstallIn(ApplicationComponent.class)
public class SentenceClicksModule {
@Singleton
@Provides
@Clicks
public int provideSentenceClicks() {
return 5;
}
}
@Module
@InstallIn(ApplicationComponent.class)
public class SentenceRepositoryModule {
@Singleton
@Provides
public SentenceRepository provideSentenceRepository(@ApplicationContext Context context, DbHelper dbHelper) {
return new SentenceRepository(context, dbHelper);
}
}
@Module
@InstallIn(ApplicationComponent.class)
public class GroupRepositoryModule {
@Singleton
@Provides
public GroupRepository provideGroupRepository(DbHelper dbHelper) {
return new GroupRepository(dbHelper);
}
}
it was working before without any dependency injection
private final SentenceRepository sentenceRepository;
private final GroupRepository groupRepository;
@ViewModelInject
SentencesViewModel(SentenceRepository sentenceRepository, GroupRepository groupRepository, @Clicks int clicks, @SentenceTypeAndDescription String[] cardArgs){
this.sentenceRepository = sentenceRepository;
this.groupRepository = groupRepository;
}
the view model is built by a component
@Component(dependencies = SentenceViewModelDependencies.class)
public interface SentenceViewModelComponent {
void inject(CardHolderFragment cardHolderFragment);
@Component.Builder
interface Builder {
Builder context(@BindsInstance Context context);
Builder appDependencies(SentenceViewModelDependencies sentenceViewModelDependencies);
SentenceViewModelComponent build();
}
}
the component needs
@EntryPoint
@InstallIn(ApplicationComponent.class)
public interface SentenceViewModelDependencies {
@SentenceTypeAndDescription String[] sentenceTypeAndDescription();
}
and the view model needs
@Module
@InstallIn(ApplicationComponent.class)
public class SentenceClicksModule {
@Singleton
@Provides
@Clicks
public int provideSentenceClicks() {
return 5;
}
}
@Module
@InstallIn(ApplicationComponent.class)
public class SentenceRepositoryModule {
@Singleton
@Provides
public SentenceRepository provideSentenceRepository(@ApplicationContext Context context, DbHelper dbHelper) {
return new SentenceRepository(context, dbHelper);
}
}
@Module
@InstallIn(ApplicationComponent.class)
public class GroupRepositoryModule {
@Singleton
@Provides
public GroupRepository provideGroupRepository(DbHelper dbHelper) {
return new GroupRepository(dbHelper);
}
}
it was working before without any dependency injection
da...@google.com <da...@google.com> #9
Is SentenceFragment
annotated with @AndroidEntryPoint
? It looks like you have setup injection of it yourself vs letting Hilt inject it.
sp...@gmail.com <sp...@gmail.com> #10
yes its annotated, not sure what you mean how could i do it myself? rather than letting hilt do it? im fairly new to Hilt and dagger2 so its most probably something I'm not doing properly
ap...@google.com <ap...@google.com> #11
Project: platform/frameworks/support
Branch: androidx-master-dev
commit 00068c24a9e483cc7a8f930e546a67b841c70382
Author: Daniel Santiago Rivera <danysantiago@google.com>
Date: Mon Aug 10 11:45:49 2020
Apply hilt-android-compiler to AndroidX's Hilt-common
The aggregating compiler has to be applied to the project
where the extension annotations are annotated with
@GeneratesRootInput so the aggregating data is generated
and therefore Hilt can correctly await for these to be
processed.
Relnote: "Fix an issue where AndroidX Hilt extension Modules would not get correctly picked up by Hilt causing ViewModels or Workers to not be available for creation."
Bug: 159540434
Test: Existing tests pass.
Change-Id: I3181c8aad0973d15d82661b48404f2eeeb7ef954
M hilt/hilt-common/build.gradle
https://android-review.googlesource.com/1395447
Branch: androidx-master-dev
commit 00068c24a9e483cc7a8f930e546a67b841c70382
Author: Daniel Santiago Rivera <danysantiago@google.com>
Date: Mon Aug 10 11:45:49 2020
Apply hilt-android-compiler to AndroidX's Hilt-common
The aggregating compiler has to be applied to the project
where the extension annotations are annotated with
@GeneratesRootInput so the aggregating data is generated
and therefore Hilt can correctly await for these to be
processed.
Relnote: "Fix an issue where AndroidX Hilt extension Modules would not get correctly picked up by Hilt causing ViewModels or Workers to not be available for creation."
Bug: 159540434
Test: Existing tests pass.
Change-Id: I3181c8aad0973d15d82661b48404f2eeeb7ef954
M hilt/hilt-common/build.gradle
da...@google.com <da...@google.com> #12
Sorry took a while since it was a bit hard to track. The next alpha version should contain contain a fix for this.
Description
Version used: com.google.dagger:hilt-android:2.28-alpha
Devices/Android versions reproduced on: nexus 5x emulator, android 9.0
If this is a bug in the library, we would appreciate if you could attach:
- Sample project to trigger the issue.
- A screenrecord or screenshots showing the issue (if UI related).
When creating a view model using the navigation scope i get an error stating that ViewModel has no zero argument constructor.
userViewModel = new ViewModelProvider(requireActivity()).get(UserViewModel.class); // works
userViewModel = new ViewModelProvider(getStoreOwner()).get(UserViewModel.class); // crashes
private ViewModelStoreOwner getStoreOwner() {
NavController navController = Navigation
.findNavController(requireActivity(), R.id.root_navigator_fragment);
if (layoutIdentifier.equals(Constants.MAIN_IDENTIFIER)) {
return navController.getViewModelStoreOwner(R.id.root_navigator);
} else {
return navController.getViewModelStoreOwner(R.id.MessageGraph);
}
}