Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to provide Context with Dagger2

I am learning Android and I am following some guides for Retrofit2 with RxJava and Dagger2. Now I want to handle no internet connection case. I've found this answer, which seems to be elegant, but I do not understand how to apply it.

I've got some NetworkModule, with OkHttpClient provider. I assume I need to create OkHttpClient.Builder with interceptor. So it should look something like this: `

@Provides
@Singleton
OkHttpClient provideOkHttpClient(Cache cache) {
    ConnectivityInterceptor ci = new ConnectivityInterceptor(networkObservable()));
    OkHttpClient.Builder.addInterceptor(ci)
    return builder.build();
}

private boolean networkObservable() {
    ConnectivityManager cm =
            (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);

    NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
    return activeNetwork != null && activeNetwork.isConnectedOrConnecting();
}

This isn't working as I don't have Context. In which direction should I go - to try to obtain context there, or maybe I misunderstand the concept of observables?

like image 748
Rumid Avatar asked Mar 09 '23 05:03

Rumid


2 Answers

You can use the @Provides annotation in your DaggerModule to obtain application Context. Alternatively you can create a module which accepts a Context parameter in its constructor in case you need activity context. Then you can build the component in your activity and inject the arguments into it.

 @Module
public class AppModule {

    private Context context;

    public AppModule(@NonNull Context context) {
        this.context = context;
    }

    @Singleton
    @Provides
    @NonNull
    public Context provideContext(){
        return context;
    }

}

Application class:

public class PFApplication extends Application {

    private static AppComponent appComponent;

    public static AppComponent getAppComponent() {
        return appComponent;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        appComponent = buildComponent();
    }

    public AppComponent buildComponent(){
        return DaggerAppComponent.builder()
                .appModule(new AppModule(this))
                .build();
    }
}
like image 85
Anton Kazakov Avatar answered Mar 16 '23 04:03

Anton Kazakov


Kotlin approach

You can provide the Application, which can be used to provide the `Context.

Define an AppComponent:

import android.app.Application
import dagger.BindsInstance
import dagger.Component
import javax.inject.Singleton

@Component
@Singleton
interface AppComponent {
  @Component.Builder
  interface Builder {
    fun build(): AppComponent

    @BindsInstance
    fun application(application: Application): Builder
  }
}

Extend Application like so:

abstract class MyApp : Application() {
    override fun onCreate() {
       super.onCreate()
       DaggerAppComponent.builder().application(this).build()
       // ..
    }
}

like image 33
Paschalis Avatar answered Mar 16 '23 03:03

Paschalis