在Android上使用Dagger和Java时,ViewModelProvider.Factory在片段上保持为空

时间:2019-05-17 01:06:15

标签: java android dagger-2 androidx android-mvp

使用Google示例GithubsampleBrowser,我陷入了尝试注入ViewModelProvider.Factory的困境。

与样本进行比较时,我发现它可以很好地运行GithubViewModelFactory,但是我的样本从来没有,我不确定我缺少什么。希望这很简单,大概是因为我使用的是androidx组件。

主要活动:

public class MainActivity extends AppCompatActivity implements HasSupportFragmentInjector {

    @Inject
    DispatchingAndroidInjector<Fragment> dispatchingAndroidInjector;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    @Override
    public DispatchingAndroidInjector<Fragment> supportFragmentInjector() {
        return dispatchingAndroidInjector;
    }
}

CategoryFragment:

public class CategoryFragment extends Fragment implements Injectable {

    @Inject
    ViewModelProvider.Factory viewModelFactory;// <-- remains null

AppInjector:

public class AppInjector {
    private AppInjector() {}
    public static void init(CrosscareApp crossCareApp) {
       DaggerAppComponent.builder().application(crossCareApp)
                .build().inject(crossCareApp);
        crossCareApp
                .registerActivityLifecycleCallbacks(new Application.ActivityLifecycleCallbacks() {
                    ........
    }

    private static void handleActivity(Activity activity) {
        if (activity instanceof HasSupportFragmentInjector) {
            AndroidInjection.inject(activity);
        }
        if (activity instanceof FragmentActivity) {
            ((FragmentActivity) activity).getSupportFragmentManager()
                    .registerFragmentLifecycleCallbacks(
                            new FragmentManager.FragmentLifecycleCallbacks() {
                                @Override
                                public void onFragmentCreated(FragmentManager fm, Fragment f,
                                        Bundle savedInstanceState) {
                                    if (f instanceof Injectable) {
                                        AndroidSupportInjection.inject(f);
                                    }
                                }
                            }, true);
        }
    }
}

AppComponent:

@Singleton
@Component(modules = {
        AndroidSupportInjectionModule.class,
        AppModule.class,
        MainActivityModule.class
})
public interface AppComponent {
    @Component.Builder
    interface Builder {
        @BindsInstance Builder application(Application application);
        AppComponent build();
    }
    void inject(CrosscareApp crosscareApp);
}

AppModule:

@Module(includes = ViewModelModule.class)
class AppModule {
    @Singleton @Provides
    CrosscareService provideCrossCareService() {
        return new Retrofit.Builder()
           ..........
    }

ViewModelModule:

@Module
abstract class ViewModelModule {
    @Binds
    @IntoMap
    @ViewModelKey(CategoryViewModel.class)
    abstract ViewModel bindCategoryViewModel(CategoryViewModel categoryViewModel);

    @Binds
    abstract ViewModelProvider.Factory bindViewModelFactory(CrosscareViewModelFactory factory);
}

CrosscareViewModel:

@Singleton
public class CrosscareViewModelFactory implements ViewModelProvider.Factory {

    private final Map<Class<? extends ViewModel>, Provider<ViewModel>> creators;

    @Inject
    public CrosscareViewModelFactory(Map<Class<? extends ViewModel>, Provider<ViewModel>> creators) {
        this.creators = creators;
    }

非常感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

毕竟,我错过了一件事。在清单中,我需要:

 android:name=".CrosscareApp"

在示例中是

 android:name=".GithubApp"

大概是目录根目录下的文件。

然后它起作用。