dagger2错误“没有@Inject构造函数或@Provides注释方法无法提供android.app.Application”

Dan*_*gan 5 java android dagger-2

我正在尝试在项目中实现dagger2,但遇到错误“ android.app.Application必须在没有@Inject构造函数或@Provides注释方法的情况下才能提供 ”。

这是我的代码:

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

di / 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);
}
Run Code Online (Sandbox Code Playgroud)

di / 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> {}
}
Run Code Online (Sandbox Code Playgroud)

di / 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);
    }
}
Run Code Online (Sandbox Code Playgroud)

di / 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();
}
Run Code Online (Sandbox Code Playgroud)

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

谢谢。

Jef*_*ica 5

在您的具体情况下,您缺少:

@Binds Application bindApplication(App app);
Run Code Online (Sandbox Code Playgroud)

这很重要,因为 dagger.android 将自动包含对特定 Application、Activity、Fragment、Service、BroadcastReceiver 等子类的绑定,但不包含对通用对象的绑定。(您可以注入App但不能注入Application,也可以注入YourActivity但不能注入Activity。)如果您想向 dagger.android 指示它应该使用您的 App 实例满足对 Application 的请求,则必须包含上面的绑定。

一般来说,这对于 Application、Activity、Service 和 BroadcastReceiver 来说是相当安全的事情,但对于 Fragment(本机或兼容库中的)则不然;这是因为 dagger.android 尊重嵌套片段,在这种情况下,注入哪个片段将是不明确的。

虽然您可以通过模块和实例字段提供应用程序,如luffy 的回答,但这比您需要的更多样板,而且优化程度也较低:Dagger 将编写代码来调用您的@Provides方法,而您可以声明性地告诉 Dagger 重用现有的方法使用@Binds或编写static @Provides避免调用实例的方法进行绑定。

查看Dagger 的优点@Binds静态调度的 Android 优点

  • ```@Binds Application bindApplication(App app); `` 应该是哪个类? (4认同)