[英]How to provide Context with Dagger2
I am learning Android and I am following some guides for Retrofit2 with RxJava and Dagger2.我正在学习 Android,我正在遵循一些使用 RxJava 和 Dagger2 进行 Retrofit2 的指南。 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.我有一些
NetworkModule
,带有OkHttpClient
提供程序。 I assume I need to create OkHttpClient.Builder
with interceptor.我假设我需要使用拦截器创建
OkHttpClient.Builder
。 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
.这不起作用,因为我没有
Context
。 In which direction should I go - to try to obtain context there, or maybe I misunderstand the concept of observables?我应该朝哪个方向走 - 尝试在那里获得上下文,或者我可能误解了可观察量的概念?
You can use the @Provides
annotation in your DaggerModule to obtain application Context. 您可以在
@Provides
中使用@Provides
批注来获取应用程序上下文。 Alternatively you can create a module which accepts a Context parameter in its constructor in case you need activity context. 或者,您可以创建一个模块,在您需要活动上下文的情况下,在其构造函数中接受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();
}
}
Just wanted to supplement @anton-kazakov's answer, to provide a way to supply activity/service context in addition to application context:只是想补充@anton-kazakov 的回答,提供一种除了应用程序上下文之外还提供活动/服务上下文的方法:
import javax.inject.Qualifier;
@Qualifier
public @interface ApplicationContext {
}
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import javax.inject.Scope;
@Scope
@Retention(RetentionPolicy.RUNTIME)
public @interface ServiceScope {
}
@Module
public class ApplicationModule {
private MyApplication mMyApplication;
public ApplicationModule(@NonNull MyApplication myApplication) {
mMyApplication = myApplication;
}
@Singleton
@Provides
@NonNull
@ApplicationContext
public Context provideApplicationContext() {
return mMyApplication;
}
}
import dagger.Module;
import dagger.Provides;
@Module
public class ServiceModule {
private final MyService mMyService;
public ServiceModule(MyService myService) {
mMyService = myService;
}
@ServiceScope
@Provides
public Context provideContext() {
return mMyService;
}
}
import javax.inject.Singleton;
import dagger.Component;
@Singleton
@Component(modules = {ApplicationModule.class})
public interface ApplicationComponent {
ServiceComponent newMyServiceComponent(ServiceModule serviceModule);
// This is optional, just putting here to show one possibility
void inject(BootCompleteReceiver bootCompleteReceiver);
}
import dagger.Subcomponent;
@ServiceScope
@Subcomponent(modules = {ServiceModule.class})
public interface ServiceComponent {
void inject(MyService myService);
}
public class MyApplication extends Application {
private ApplicationComponent mApplicationComponent;
@Override
public void onCreate() {
// mApplicationComponent = DaggerApplicationModule.builder()
// .applicationModule(new ApplicationModule(this))
// .build();
super.onCreate();
}
/**
* Note: {@link ContentProvider#onCreate} is called before
* {@link Application#onCreate}, hence if you have a
* {@link ContentProvider}, inject here instead of
* in {@link Application#onCreate}.
* <p>
* https://stackoverflow.com/a/44413873
* <p>
* https://stackoverflow.com/questions/9873669/how-do-i-catch-content-provider-initialize
*
* @param base The base Context.
*/
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
mApplicationComponent = DaggerApplicationComponent.builder()
.applicationModule(new ApplicationModule(this))
.build();
}
public ApplicationComponent getApplicationComponent() {
return mApplicationComponent;
}
}
import javax.inject.Inject;
public class MyService extends Service {
@Override
public void onCreate() {
((MyApplication) getApplicationContext())
.getApplicationComponent()
.newMyServiceComponent(new ServiceModule(this))
.inject(this);
super.onCreate();
}
}
https://dagger.dev/api/2.19/dagger/Component.html https://dagger.dev/api/2.19/dagger/Module.html#subcomponents-- https://dagger.dev/api/2.19/dagger/Component.html https://dagger.dev/api/2.19/dagger/Module.html#subcomponents--
You can provide the Application
, which can be used to provide the `Context.您可以提供
Application
,它可用于提供 `Context.
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
}
}
abstract class MyApp : Application() {
override fun onCreate() {
super.onCreate()
DaggerAppComponent.builder().application(this).build()
// ..
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.