2017-12-27 17 views
0

私は自分のプロジェクトでDagger2リリースのライブラリを使用しています。私は呼び出しています、DaggerでIntentServiceを挿入する方法

@Module 
public class SplashActivityModule { 

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

:次にActivityBuilderのように特定の活動と関連モジュールを定義します

@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); 
} 

@Module 
public abstract class ActivityBuilder { 

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

とSplashActivityModuleのように依存関係を提供している私はとAppComponentを定義していますSplashActivityのIntentService(いくつかの設定データをロードする)が、そのIntentServiceの中には、SharePreference、AppExecutersなどの@Inject依存関係はできません。AppM私はのonCreate内部のように注入しようとしています と内部SetupDataService:Update_1 **

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

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

:oduleは次のように定義されて

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 
    { 
    } 
} 
} 

それは私がしようとした場合でも、私たちは注入することはできません。アプリケーションクラス内にHasServiceInjectorを実装します。それは以下のようにスローされます: '@Provideまたは@Produceなしでサービスを挿入できません'。 ** Update_1はここで終了

..

はどのようにDagger2.11リリースを使用してテントのサービスを注入します。私は定義しようとしました:AppComponentの中で

void inject(IntentService intentService); 

でも、私は依存性を注入中に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'メソッドを呼び出すと、https://github.com/google/dagger/blob/master/java/dagger(あなたは[ContributesAndroidInjector' @サービスを注入するために'使用]と考えられてい/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のために存在します。あなたは、あなたのSetupDataServiceバインディング@ContributesAndroidInjectorにインストールモジュールにそれらを自分で追加することができます。

@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

私は独立して、あるいはSplashActivityにリンクしてみましたAcitivityBuilder内ContributesAndroidInjector @使用してみました - > contributeinjector。しかし不運にも、どちらもうまくいきませんでした。私はまだSharedPreferenceUtilsの依存関係を注入している間にnullオブジェクトを取得しています。私は何か見落としてますか ?ありがとう。 – prdp89

+0

prdp89 @それはあなたがどこか、どのようにSharedPreferenceUtilsを注入している私たちを示していないようあなたは、何かを逃したければ言うことは不可能です。再現可能な例がなければ、エラーメッセージに基づいて推測する必要があります。 –

+0

編集を確認してください。ありがとう。 – prdp89

関連する問題