如何在Dagger2.11中注入IntentService

问题描述 投票:1回答:1

我在我的项目中使用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:和Inside 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在这里结束..

这里有任何帮助..

谢谢。

android dagger-2 dagger
1个回答
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存在的绑定。您可以将它们自己添加到您在@ContributesAndroidInjectorSetupDataService绑定上安装的模块中:

@ContributesAndroidInjector(modules = SetupDataServiceModule.class)
SetupDataService bindSetupDataService();

@Module interface SetupDataServiceModule {
  @Binds Service bindService(SetupDataService service);
  @Binds IntentService bindIntentService(SetupDataService service);
}

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

有关更多背景知识,请参阅this answer from yesterday,包括为什么要在此处为​​服务而不是为碎片执行此操作。

© www.soinside.com 2019 - 2024. All rights reserved.