如何使用Dagger2

时间:2018-05-10 05:38:29

标签: android mvvm retrofit2 dagger-2 android-viewmodel

我正在尝试在现有项目中实现新架构(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天。请帮忙,建议。谢谢。如果你不愿意帮助,请不要贬低。

0 个答案:

没有答案