如何在Dagger2.11中注入IntentService

时间:2017-12-27 11:29:41

标签: android dagger-2 dagger

我在我的项目中使用Dagger2发布的库。我已将AppComponent定义为:

  @Singleton
@Component(modules = {
        AndroidInjectionModule.class, AppModule.class, ActivityBuilder.class })
public interface AppComponent {

    @Component.Builder
    interface Builder {

        @BindsInstance
        Builder application(Application application);

        AppComponent build();
    }

    void inject(TraderApplication traderApplication);
}

然后,ActivityBuilder将特定活动和相关模块定义为:

 @Module
public abstract class ActivityBuilder {

    @ContributesAndroidInjector(modules = SplashActivityModule.class)
    abstract SplashActivity bindSplashActivity();
}

和SplashActivityModule提供依赖关系:

  @Module
public class SplashActivityModule {

    @Provides
    SplashViewModel provideLoginViewModel(TraderRepository traderRepository, Application application, SharedPreferenceUtils sharedPreferenceUtils, AppExecutors appExecutors) {
        return new SplashViewModel(traderRepository, application, sharedPreferenceUtils, appExecutors);
    }
}

现在,我从SplashActivity调用一个IntentService(加载一些设置数据),但在IntentService内部我无法@Inject依赖于SharePreference,AppExecuters等.AppModule定义为:

@Module
public class AppModule {
@Provides
    @Singleton
    TraderRepository provideIssueRepository(TraderListRepositoryImpl repository) {
        return repository;
    }

 @Provides
    @Singleton
    SharedPreferences providesSharedPreferences(Application application) {
        return PreferenceManager.getDefaultSharedPreferences(application);
    }
}

** Update_1: 和SetupDataService内部我试图像onCreate一样注入:

  public class SetupDataService extends IntentService implements HasServiceInjector {

    @Inject
        SharedPreferenceUtils mSharedPreferenceUtils;

         @Inject
            AndroidInjector<Service> fragmentDispatchingAndroidInjector;

            @Override
            public AndroidInjector<Service> serviceInjector() {
                return fragmentDispatchingAndroidInjector;
            }

            @Override
            public void onCreate() {
                AndroidInjection.inject(this);
                super.onCreate();
            }
    @Override
        protected void onHandleIntent(@Nullable Intent intent) {
            assert intent != null;

    //**update_2 :
    if(mSharedPreferenceUtils != null) //still null here after using @binds
    {
    }
 }
}

即使我尝试在Application Class中实现HasServiceInjector,它也不允许我们注入。它抛出: '不能在没有@Provide或@Produce的情况下注入服务。

** Update_1在这里结束..

如何使用Dagger2.11版本注入Intent服务。我尝试定义:

 void inject(IntentService intentService);

在AppComponent中,但是,我仍然在注入依赖项时获取NULL值。

** Update_2:

我尝试在Service类中注入的SharedPreferenceUtils类在onHandleIntent中返回null:

@Singleton
public class SharedPreferenceUtils {

    //region Private Fields
    private SharedPreferences mSharedPreferences;
    private final String TAG = SharedPreferenceUtils.class.getSimpleName();
    private final Method APPLY_METHOD = findApplyMethod();
    //endregion

    @Inject
    public SharedPreferenceUtils(SharedPreferences mSharedPreferences) {
        this.mSharedPreferences = mSharedPreferences;
    }
}

** Update_2在此结束..

这里有任何帮助..

感谢。

1 个答案:

答案 0 :(得分:0)

  

即使我尝试在Application Class中实现HasServiceInjector。它抛出:'不能在没有@Provide或@Produce的情况下注入服务。

这里要做的正确的事情就是这样做:让你的应用程序实现HasServiceInjector。 AndroidInjection.inject()的要点是您正在使用Android创建的对象,因此无法自然访问您的DI图,并让它自动将应用程序转换为HasServiceInjector,以便它可以尝试注入服务。请参阅AndroidInjection中的实施(已添加评论):

public static void inject(Service service) {
  checkNotNull(service, "service");
  Application application = service.getApplication();
  // Don't even bother checking the service itself, just check the Application.
  if (!(application instanceof HasServiceInjector)) {
    throw new RuntimeException(
        String.format(
            "%s does not implement %s",
            application.getClass().getCanonicalName(),
            HasServiceInjector.class.getCanonicalName()));
  }

  // As long as serviceInjector() returns non-null...
  AndroidInjector<Service> serviceInjector =
      ((HasServiceInjector) application).serviceInjector();
  checkNotNull(serviceInjector, "%s.serviceInjector() returned null",
      application.getClass());

  // ...ask it to inject your service.
  serviceInjector.inject(service);
}

听起来你真正的问题是你正在尝试注入Service,这是不允许的:你可以注入SetupDataService,但是没有Service或IntentService存在的绑定。您可以自己将它们添加到您在@ContributesAndroidInjector的{​​{1}}绑定上安装的模块中:

SetupDataService

...但除非您正在编写可用于多个服务的可重用代码,或者除非您已经构建了图形约束并且试图避免在其他代码段中直接引用SetupDataService,否则您可能只想坚持改为注入SetupDataService。

请参阅this answer from yesterday了解更多背景信息,包括您希望在此处为服务而不是片段进行此操作的原因。