Dagger 2注入Android Context

use*_*637 30 android dependency-injection android-context dagger-2

我正在使用Dagger 2并使其工作,但我现在需要访问Android应用程序上下文.

我不清楚如何注入和访问上下文.我试过这样做如下:

@Module
public class MainActivityModule {    
    private final Context context;

    MainActivityModule(Context context) {
        this.context = context;
    }

@Provides @Singleton
Context provideContext() {
    return context;
}
Run Code Online (Sandbox Code Playgroud)

但是,这会导致以下异常:

java.lang.RuntimeException:无法创建应用程序:java.lang.IllegalStateException:必须设置mainActivityModule

如果我检查Dagger生成的代码,则会在此处引发此异常:

public Graph build() {  
    if (mainActivityModule == null) {
        throw new IllegalStateException("mainActivityModule must be set");
    }
    return new DaggerGraph(this);
}
Run Code Online (Sandbox Code Playgroud)

我不确定这是否是注入Context的正确方法 - 任何帮助将不胜感激.

Epi*_*rce 24

@Module
public class MainActivityModule {    
    private final Context context;

    public MainActivityModule (Context context) {
        this.context = context;
    }

    @Provides //scope is not necessary for parameters stored within the module
    public Context context() {
        return context;
    }
}

@Component(modules={MainActivityModule.class})
@Singleton
public interface MainActivityComponent {
    Context context();

    void inject(MainActivity mainActivity);
}
Run Code Online (Sandbox Code Playgroud)

然后

MainActivityComponent mainActivityComponent = DaggerMainActivityComponent.builder()
    .mainActivityModule(new MainActivityModule(MainActivity.this))
    .build();
Run Code Online (Sandbox Code Playgroud)

  • 因为它不需要作用域提供者来提供相同的实例。它只会存在一次,因为它总是从模块中的字段提供 (2认同)

kei*_*sar 15

我花了一段时间才找到合适的解决方案,所以我认为这可能会为其他人节省一些时间,据我所知,这是当前 Dagger 版本 (2.22.1) 的首选解决方案。

在下面的示例中,我需要Application'sContext来创建一个RoomDatabase(发生在StoreModule)。

如果您看到任何错误或错误,请告诉我,以便我也学习:)

成分:

// We only need to scope with @Singleton because in StoreModule we use @Singleton
// you should use the scope you actually need
// read more here https://google.github.io/dagger/api/latest/dagger/Component.html
@Singleton
@Component(modules = { AndroidInjectionModule.class, AppModule.class, StoreModule.class })
public interface AwareAppComponent extends AndroidInjector<App> {

    // This tells Dagger to create a factory which allows passing 
    // in the App (see usage in App implementation below)
    @Component.Factory
    interface Factory extends AndroidInjector.Factory<App> {
    }
}
Run Code Online (Sandbox Code Playgroud)

应用模块:

@Module
public abstract class AppModule {
    // This tell Dagger to use App instance when required to inject Application
    // see more details here: https://google.github.io/dagger/api/2.22.1/dagger/Binds.html
    @Binds
    abstract Application application(App app);
}
Run Code Online (Sandbox Code Playgroud)

存储模块:

@Module
public class StoreModule {
    private static final String DB_NAME = "aware_db";

    // App will be injected here by Dagger
    // Dagger knows that App instance will fit here based on the @Binds in the AppModule    
    @Singleton
    @Provides
    public AppDatabase provideAppDatabase(Application awareApp) {
        return Room
                .databaseBuilder(awareApp.getApplicationContext(), AppDatabase.class, DB_NAME)
                .build();
    }
}
Run Code Online (Sandbox Code Playgroud)

应用程序:

public class App extends Application implements HasActivityInjector {

    @Inject
    DispatchingAndroidInjector<Activity> dispatchingAndroidInjector;

    @Override
    public void onCreate() {
        super.onCreate();

        // Using the generated factory we can pass the App to the create(...) method
        DaggerAwareAppComponent.factory().create(this).inject(this);
    }

    @Override
    public AndroidInjector<Activity> activityInjector() {
        return dispatchingAndroidInjector;
    }
}
Run Code Online (Sandbox Code Playgroud)


Ado*_*vez 9

我读过这篇文章,它非常有帮助。

https://medium.com/tompee/android-dependency-injection-using-dagger-2-530aa21961b4

示例代码。

更新:我从 AppComponent.kt 中删除了这些行,因为不是必需的

fun context(): Context
fun applicationContext(): Application
Run Code Online (Sandbox Code Playgroud)

应用程序组件.kt

   @Singleton
    @Component(
        modules = [
            NetworkModule::class,
            AppModule::class
        ]
    )
    interface AppComponent {
        fun inject(viewModel: LoginUserViewModel)
    }
Run Code Online (Sandbox Code Playgroud)

应用程序模块.kt

@Module
class AppModule(private val application: Application) {

    @Provides
    @Singleton
    fun providesApplication(): Application = application

    @Provides
    @Singleton
    fun providesApplicationContext(): Context = application

    @Singleton
    @Provides
    fun providesNetworkConnectivityHelper(): NetworkConnectivityHelper{
        return NetworkConnectivityHelper(application.applicationContext)
    }
}
Run Code Online (Sandbox Code Playgroud)

网络连接助手.kt

并且只添加了 @Inject 构造函数来传递 Context

class NetworkConnectivityHelper @Inject constructor(context: Context) {

    private val connectivityManager =
        context.getSystemService(CONNECTIVITY_SERVICE) as ConnectivityManager

    @Suppress("DEPRECATION")
    fun isNetworkAvailable(): Boolean {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            val nc = connectivityManager.getNetworkCapabilities(connectivityManager.activeNetwork)

            nc != null
                    && nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
                    && nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)
        }

        val networkInfo = connectivityManager.activeNetworkInfo
        return networkInfo != null && networkInfo.isConnected
    }
}
Run Code Online (Sandbox Code Playgroud)

应用程序类.kt

class App : Application() {

    lateinit var appComponent: AppComponent

    override fun onCreate() {
        super.onCreate()
        this.appComponent = this.initDagger()
    }

    private fun initDagger() = DaggerAppComponent.builder()
        .appModule(AppModule(this))
        .build()
}
Run Code Online (Sandbox Code Playgroud)

最后在我的活动中我注入了我的助手

 @Inject lateinit var networkConnectivity: NetworkConnectivityHelper
Run Code Online (Sandbox Code Playgroud)

还有耶!这个对我有用。