如果没有@Inject构造函数或@ Provide-annotated方法,则无法提供dagger2错误“android.app.Application”。 [英] dagger2 error "android.app.Application cannot be provided without an @Inject constructor or from an @Provides-annotated method"

查看:2104
本文介绍了如果没有@Inject构造函数或@ Provide-annotated方法,则无法提供dagger2错误“android.app.Application”。的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在我的项目中实现dagger2,但是我遇到了一个错误没有@Inject构造函数或者@Project-annotated方法无法提供android.app.Application

I'm trying to implement dagger2 in my project, but I'm faced with an error "android.app.Application cannot be provided without an @Inject constructor or from an @Provides-annotated method".

这是我的代码:

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

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

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

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

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

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

谢谢。

推荐答案

在您的具体情况下,您将失踪:

In your specific case, you're missing:

@Binds Application bindApplication(App app);

这很重要因为dagger.android会自动包含对特定应用程序,活动的绑定,Fragment,Service,BroadcastReceiver等子类,但不是通用对象。 (您可以注入 App 但不能应用 YourActivity ,但不能注入活动。)如果您想要向dagger.android表明它应该使用您的App实例满足应用程序的请求,您必须包含上面的绑定。

This is important because dagger.android will automatically include a binding to the specific Application, Activity, Fragment, Service, BroadcastReceiver, etc subclass but not the general object. (You'd be able to inject App but not Application, and YourActivity but not Activity.) If you want to indicate to dagger.android that it should fulfill requests for Application using your App instance, you have to include a binding as above.

一般来说,这是一个漂亮的为Application,Activity,Service和BroadcastReceiver做的安全事情,但不是片段(本机或compat库);这是因为dagger.android尊重嵌套片段,在这种情况下,注入Fragment将是不明确的。

Generally speaking, this is a pretty safe thing to do for Application, Activity, Service, and BroadcastReceiver, but not Fragment (native or in the compat libraries); this is because dagger.android respects nested fragments, and in that case it would be ambiguous which Fragment to inject.

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

Though you can provide the Application through a Module and instance field as in luffy's answer, this is more boilerplate than you need, and is also less optimized: Dagger will write code to call your @Provides method, whereas you can declaratively tell Dagger to reuse an existing binding using @Binds or write a static @Provides method that avoids invoking the call on an instance.

参见 @Binds 的Dagger优势 Android静态调度的优势

See the Dagger advantages of @Binds and the Android advantages of static dispatch.

这篇关于如果没有@Inject构造函数或@ Provide-annotated方法,则无法提供dagger2错误“android.app.Application”。的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆