使用Dagger2为Fragment的ViewModel注入依赖遇空值问题求助
Hey there, let's dig into why your FollowingViewModel is coming up null in your nested FollowingListFragment! I’ve looked over your code snippets and spotted a few key gaps that are likely causing this issue. Let’s fix them step by step.
1. Ensure FollowingListFragment Implements the Injectable Marker Interface
Looking at your AppInjector code, it only triggers dependency injection for fragments that implement Injectable:
if (f instanceof Injectable) { AndroidSupportInjection.inject(f); }
If your FollowingListFragment doesn’t implement this interface, Dagger will never inject its dependencies (including the MyViewModelFactory you need to create the ViewModel). Update your fragment like this:
public class FollowingListFragment extends Fragment implements Injectable { @Inject MyViewModelFactory viewModelFactory; private FollowingViewModel followingViewModel; @Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Use the injected factory to get your ViewModel (don't instantiate it directly!) followingViewModel = ViewModelProviders.of(this, viewModelFactory) .get(FollowingViewModel.class); } // Rest of your fragment code... }
2. Fix Your Incomplete MyViewModelFactory
Your MyViewModelFactory code cuts off mid-method, which means it can’t properly resolve and create ViewModel instances. Here’s the complete, working implementation:
@Singleton public class MyViewModelFactory extends ViewModelProvider.NewInstanceFactory { private final Map<Class<? extends ViewModel>, Provider<ViewModel>> creators; @Inject public MyViewModelFactory(Map<Class<? extends ViewModel>, Provider<ViewModel>> creators) { this.creators = creators; } @SuppressWarnings("unchecked") @Override public <T extends ViewModel> T create(Class<T> modelClass) { Provider<? extends ViewModel> creator = creators.get(modelClass); // Fall back to checking for parent classes if exact match isn't found if (creator == null) { for (Map.Entry<Class<? extends ViewModel>, Provider<ViewModel>> entry : creators.entrySet()) { if (modelClass.isAssignableFrom(entry.getKey())) { creator = entry.getValue(); break; } } } if (creator == null) { throw new IllegalArgumentException("Unknown ViewModel class: " + modelClass); } try { return (T) creator.get(); } catch (Exception e) { throw new RuntimeException(e); } } }
3. Add @Inject to FollowingViewModel’s Constructor
For Dagger to create FollowingViewModel instances and inject its dependencies (like Repository or CompositeDisposable), its constructor must be annotated with @Inject:
public class FollowingViewModel extends ViewModel { private final Repository repository; private final CompositeDisposable compositeDisposable; // Critical: Add @Inject here so Dagger knows how to create this ViewModel @Inject public FollowingViewModel(Repository repository, CompositeDisposable compositeDisposable) { this.repository = repository; this.compositeDisposable = compositeDisposable; } // Your ViewModel business logic... }
4. Double-Check Dagger Module Associations
From your code, these already look correct, but it’s worth verifying:
FragmentBuildersModuleis correctly included inHomeActivity’s@ContributesAndroidInjector(you have@ContributesAndroidInjector(modules = FragmentBuildersModule.class)which is right)ViewModelModuleis included inAppModule(your@Module(includes = { ViewModelModule.class})is correct)
5. Confirm Fragment Attachment
Make sure you’re adding FollowingListFragment via the FragmentActivity’s supportFragmentManager (not a custom fragment manager), so the AppInjector’s fragment lifecycle callback triggers onFragmentCreated and injects the fragment.
After making these changes, your FollowingViewModel should be properly injected and no longer null!
内容的提问来源于stack exchange,提问作者Satwinder Singh

