2017-12-22 30 views
0

私のプロジェクトでdagger2を実装しようとしていますが、 "android .app.Applicationは@Injectコンストラクタなしで、または@ Provides-annotatedメソッド "から提供することはできません。dagger2エラー "android.app.Applicationは@Injectコンストラクタなしで提供することも、@ Provides-annotatedメソッドから提供することもできません"

ここに私のコードです:

App.java

package com.poppmedia.wallpaperautomaton; 

import android.app.Application; 

import com.poppmedia.wallpaperautomaton.di.DaggerAppComponent; 

import dagger.android.AndroidInjector; 
import dagger.android.DaggerApplication; 

/** 
* The Android {@link Application}. 
*/ 
public class App extends DaggerApplication { 
    @Override 
    protected AndroidInjector<? extends DaggerApplication> applicationInjector() { 
     return DaggerAppComponent.builder().create(this); 
    } 
} 

ディ/ AppModule.java

package com.poppmedia.wallpaperautomaton.di; 

import android.app.Application; 
import android.content.Context; 

import javax.inject.Singleton; 

import dagger.Binds; 
import dagger.Module; 

/** 
* Provider application-wide dependencies. 
*/ 
@Module 
public interface AppModule { 
    @Binds 
    @Singleton 
    Context bindContext(Application application); 
} 

ディ/ AppComponent.java

は、
package com.poppmedia.wallpaperautomaton.di; 

import com.poppmedia.wallpaperautomaton.App; 

import javax.inject.Singleton; 

import dagger.Component; 
import dagger.android.AndroidInjector; 
import dagger.android.support.AndroidSupportInjectionModule; 

/** 
* Injects application dependencies. 
*/ 
@Singleton 
@Component(modules = { 
     AndroidSupportInjectionModule.class, 
     AppModule.class, 
}) 
public interface AppComponent extends AndroidInjector<App> { 
    @Component.Builder 
    abstract class Builder extends AndroidInjector.Builder<App> {} 
} 

ジ/ TestClassModule.java

package com.poppmedia.wallpaperautomaton.di; 

import android.content.Context; 

import com.poppmedia.wallpaperautomaton.TestClass; 

import javax.inject.Singleton; 

import dagger.Module; 
import dagger.Provides; 

@Module 
public class TestClassModule { 
    @Provides 
    @Singleton 
    TestClass provideTestClass(Context context) { 
     return new TestClass(context); 
    } 
} 

ジ/ TestClassComponent.java

package com.poppmedia.wallpaperautomaton.di; 

import com.poppmedia.wallpaperautomaton.TestClass; 

import javax.inject.Singleton; 

import dagger.Component; 

@Singleton 
@Component(modules = { AppModule.class, TestClassModule.class }) 
public interface TestClassComponent { 
    TestClass getTestClass(); 
} 

TestClass.java

package com.poppmedia.wallpaperautomaton; 

import android.content.Context; 

import javax.inject.Inject; 
import javax.inject.Singleton; 

@Singleton 
public class TestClass { 
    private Context mContext; 

    @Inject 
    public TestClass(Context context) { 
     mContext = context; 
    } 
} 

ありがとうございます。

+1

私はコンポーネントビルダーであなたの 'Application'をバインドすることも、モジュールビルダーにそれを追加することもしません。 ( ' **ジ/ AppComponent.java ** 'アプリケーションgetApplication; **ジ/ AppModule.java ** '@Binds @SingletonアプリケーションbindApplication(アプリケーションのアプリケーション): –

+0

私は次のように追加しようとしました); ' 依存サイクルエラーが発生しました。 –

+0

@DanielGorgan '@Binds Application bindApplication(App app);で試して、' App'というカスタム実装に一般的な 'Application'オブジェクトをバインドするようにしてください。あなたは '@ Singleton'を取ったり出たりすることができますが、私はそれを残しておきます。 –

答えて

0

、あなたが不足している:

@Binds Application bindApplication(App app); 

をdagger.androidが自動的に特異的に結合アプリケーション、活動、フラグメント、サービス、BroadcastReceiverを、含まれていますので、これは重要ですetcサブクラスではなく、一般オブジェクトではありません。 (あなたはのAppを注入することができると思いますがないアプリケーション、およびYourActivityなく活動。)あなたはそれがあなたのアプリケーションのインスタンスを使用したアプリケーションの要求を満たす必要があることをdagger.androidに指示したい場合は、上記のようなバインディングを含める必要があります。

一般的に言って、これはApplication、Activity、Service、BroadcastReceiverではかなり安全ですが、Fragment(ネイティブまたは互換ライブラリではありません)ではできません。これは、dagger.androidがネストしたフラグメントを尊重し、その場合、フラグメントが挿入するのが曖昧になるためです。

あなたはluffy's answerのようにモジュールとインスタンスフィールドを介してアプリケーションを提供することができますが、これはあなたが必要以上の定型であり、また、より少ない最適化されている:あなたが宣言ダガーを伝えることができるのに対し、ダガーは、あなたの@Providesメソッドを呼び出すコードを記述します@Bindsを使用して既存のバインドを再利用するか、インスタンスに対してコールを呼び出さないようにstatic @Providesメソッドを記述します。

the Dagger advantages of @Bindsおよびthe Android advantages of static dispatchを参照してください。

-1

AppModuleでは、@あなたはアプリケーションをバインドしますが、他のモジュールはアプリケーションを提供していません。

アプリケーションはAndroidフレームワークによって作成されるため、AppModuleに外部からアプリケーションを提供させる必要があります。あなたの特定のケースで

@Module 
public class AppModule { 
    private Application mApp; 
    public AppModule(Application app) { 
     mApp = app 
    } 
    @Singleton 
    Context provideContext() { 
     return mApp 
    } 
} 
+0

これはこれを実行する最良の方法ではありません。既に 'App'のバインディングがあります。このような単純なバインディングの場合は、' @Binds'または '@BindsInstance'を使用することをお勧めします。 –

関連する問題