ViewModelProvider.Factory 在使用 Dagger 的片段上保持为空,在 Android 上保持 Java
ViewModelProvider.Factory remains null on fragment using Dagger and Java on Android
使用 google 示例 GithubsampleBrowser 我一直无法尝试注入 ViewModelProvider.Factory。
与示例进行比较时,我发现它在 GithubViewModelFactory 中运行正常,但我的从来没有运行过,我不确定我遗漏了什么。希望这是非常简单的事情,大概是因为我正在使用 androidx 组件。
主要Activity:
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;
}
}
类别片段:
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);
}
}
}
应用程序组件:
@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);
}
应用模块:
@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;
}
非常感谢任何帮助。
毕竟,我错过了一件事。在清单中,我需要:
android:name=".CrosscareApp"
在示例中,它是
android:name=".GithubApp"
大概是目录根目录下的文件。
然后就可以了。
使用 google 示例 GithubsampleBrowser 我一直无法尝试注入 ViewModelProvider.Factory。
与示例进行比较时,我发现它在 GithubViewModelFactory 中运行正常,但我的从来没有运行过,我不确定我遗漏了什么。希望这是非常简单的事情,大概是因为我正在使用 androidx 组件。
主要Activity:
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;
}
}
类别片段:
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);
}
}
}
应用程序组件:
@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);
}
应用模块:
@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;
}
非常感谢任何帮助。
毕竟,我错过了一件事。在清单中,我需要:
android:name=".CrosscareApp"
在示例中,它是
android:name=".GithubApp"
大概是目录根目录下的文件。
然后就可以了。