2017-12-27 155 views
0

我在我的项目中使用了Dagger2发布的库。我已经定义AppComponent为:如何在Dagger2.11中注入IntentService

@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等的依赖关系.AppM odule被定义为:

@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释放注入意向的服务。我试图定义:

void inject(IntentService intentService); 

里面的AppComponent,但仍然,我注入依赖项时获得NULL值。

** Update_2:

和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到此为止..

任何帮助这里..

谢谢。

+0

,你能否告诉我们IntentService?凡在这对你们所说的'inject'方法,你向我们展示了,和你有没有考虑[使用'@ ContributesAndroidInjector'注入服务(https://github.com/google/dagger/blob/master/java/dagger /android/AndroidInjection.java#L127)? –

+0

@JeffBowman请检查* Update_1编辑。谢谢。 – prdp89

回答

0

即使我试图在应用程序类中实现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); 
} 

这听起来像你真正的问题是,你试图注入服务,这是不允许的:你可以注入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

+0

我尝试使用@ ContributesAndroidInjector内部AcitivityBuilder独立地或者甚至试图链接到SplashActivity - > contributeinjector。但不幸的是两者都没有奏效。在注入SharedPreferenceUtils依赖项时,我仍然得到空对象。我错过了什么 ?谢谢。 – prdp89

+0

@ prdp89这是不可能的说,如果你错过了什么,因为你还没有告诉我们哪里或你如何注入SharedPreferenceUtils。没有可重复的例子,我必须根据你的错误信息来猜测。 –

+0

请检查编辑。谢谢。今天 – prdp89