我正在尝试在现有项目中实现新架构(MVVM + RxJava2 + Dagger2 + Retrofit)。我已经建立了整个上面的架构并在HomeActivity上进行了测试。在HomeViewModel中注入的依赖项。所以现在我试图在FollowFragment的FollowViewModel中注入与HomeViewModel相同的依赖项,这是HomeActivity的容器片段。但是注入的依赖项总是返回null(Not Initiziling)。我正在关注此项目riggaroo/android-arch-components-date-countdown以注入依赖项,但在此示例中,仅使用活动而不使用片段。所以我不知道发生了什么以及在多个ViewModel中注入deps的人。
以下是要理解的一些重要类的代码:
AppApplication.class
public class AppApplication extends MultiDexApplication implements HasActivityInjector {
@Inject
DispatchingAndroidInjector<Activity> dispatchingAndroidInjector;
@Override
public void onCreate() {
...........................
AppInjector.init(this)
..........................
}
@Override
public AndroidInjector<Activity> activityInjector() {
return dispatchingAndroidInjector;
}
}
AppInjector.class
public class AppInjector {
private AppInjector() {
}
public static void init(AppApplication appApplication) {
DaggerAppComponent.builder()
.application(appApplication)
.build()
.inject(appApplication);
appApplication
.registerActivityLifecycleCallbacks(new Application.ActivityLifecycleCallbacks() {
@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
handleActivity(activity);
}
});
}
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.class
@Singleton
@Component(modules = {AndroidSupportInjectionModule.class,ActivityBuilderModule.class, AppModule.class, NetworkModule.class})
public interface AppComponent {
@Component.Builder
interface Builder {
@BindsInstance
Builder application(AppApplication application);
AppComponent build();
}
void inject(AppApplication app);
AppModule.class
@Module(includes = { ViewModelModule.class})
public class AppModule {
@Provides
Context provideContext(AppApplication application) {
return application.getApplicationContext();
}
}
ActivityBuilderModule.class
@Module
public abstract class ActivityBuilderModule {
@ContributesAndroidInjector(modules = FragmentBuildersModule.class)
abstract HomeActivity bindHomeActivity();
}
FragmentBuildersModule.class
@Module
public abstract class FragmentBuildersModule {
@ContributesAndroidInjector
abstract FollowingListFragment contributeFollowingListFragment();
}
ViewModule.class
@Module
public abstract class ViewModelModule {
@Binds
@IntoMap
@ViewModelKey(FollowingViewModel.class)
abstract ViewModel bindFollowingViewModel(FollowingViewModel followingViewModel);
@Binds
@IntoMap
@ViewModelKey(HomeViewModel.class)
abstract ViewModel bindHomeViewModel(HomeViewModel homeViewModel);
@Binds
abstract ViewModelProvider.Factory bindViewModelFactory(MyViewModelFactory factory);
}
NetworkModule.class
@Module
public class NetworkModule {
public NetworkModule(){}
@Provides
@Singleton
CompositeDisposable getCompositeDisposable() {
return new CompositeDisposable();
}
@Provides
@Singleton
Retrofit provideCall() {
// OKHttps and Retrofit code...
}
@Provides
@Singleton
@SuppressWarnings("unused")
public ApiCallInterface providesNetworkService(
Retrofit retrofit) {
return retrofit.create(ApiCallInterface.class);
}
@Provides
@Singleton
@SuppressWarnings("unused")
public Repository providesService(
ApiCallInterface networkService) {
return new Repository(networkService);
}
}
MyViewModelFactory.class
@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);
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 model class " + modelClass);
}
try {
return (T) creator.get();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
此类用于创建所有viewModel的实例。我已经调试过,发现只有HomeViewModel实例正在创建。
现在我创建了从HomeActivity调用的HomeViewModel。哪个工作正常。现在,相同的实现在FollowFragment中完成,但不起作用。让我向您展示我如何从FollowingListFragment.class初始化FollowViewModel
public class FollowingListFragment extends BaseFragment implementsInjectable {
@Inject
MyViewModelFactory myViewModelFactory;
private FollowingViewModel followingViewModel;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mContext = getActivity();
followingViewModel = ViewModelProviders.of(this, plownsViewModelFactory)
.get(FollowingViewModel.class);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_following_list, container, false);
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
followingViewModel.getFollowings(id,curser);
}
}
这是FollowViewModel.class
public class FollowingViewModel extends ViewModel {
@Inject
Repository service;
@Inject
CompositeDisposable subscriptions;
@Inject
public FollowingViewModel() {
}
/*void setService(Repository service){
this.service = service;
}*/
void getFollowings(String id,String curser) {
if(service!=null) { **//HERE SERVICE RETURNS NULL**
Disposable subscription = service.getFollowings(id, curser, new IResponseCallback<FollowingResponse.FollowingResult>() {
@Override
public void onSuccess(FollowingResponse.FollowingResult followingResult) {
}
@Override
public void onError(Throwable throwable) {
}
});
subscriptions.add(subscription);
}else {
Log.d("FollowViewModel", "Service is null " );
}
}
这是HomeActivity和HomeViewModel类代码,它工作正常。 HomeActivity.class
public class HomeActivity extends BaseActivity implements HasSupportFragmentInjector, Injectable {
@Inject
DispatchingAndroidInjector<Fragment> supportFragmentInjector;
@Inject
MyViewModelFactory viewFactory;
HomeViewModel homeViewModel;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
homeViewModel = ViewModelProviders.of(this,viewFactory).get(HomeViewModel.class);
homeViewModel.getFollowings("xyx",null);
}
@Override
public AndroidInjector<Fragment> supportFragmentInjector() {
return supportFragmentInjector;
}
}
HomeViewModel.class
public class HomeViewModel extends ViewModel {
@Inject
Repository service;
@Inject
CompositeDisposable subscriptions;
@Inject
public HomeViewModel() {
}
void getFollowings(String id,String curser) {
if(service!=null) { **// Returing null service**
}
}else {
Log.d("FollowViewModel", "Service is null " );
}
}
}
我挣扎了2天。请帮忙,建议。谢谢。如果你不愿意帮助,请不要贬低。