我试图围绕我的问题谷歌,但仍然不知道我做错了什么。
案例:有一个NetworkModule
,它提供了构建Retrofit
对象所需的所有内容(也提供了它)。
其中一个部分是Interceptor
OkHttpClient
,其中设置了所有请求的HTTP标头。
在应用用户未获得授权之前,我不想对此特定Interceptor
执行任何操作,但是一旦应用收到access_token
,我就会将其设置为Interceptor
,以便它使用此特定access_token
设置了另一个标头。
谷歌的答案被认为是一种正确的方法是公开此Interceptor
以便能够在需要时设置此access_token
。
所以我做了什么:
这是我的AppComponent:
@ApplicationScope
@Component(modules = [
AppModule::class,
DataModule::class,
NetworkModule::class,
NetworkServicesModule::class,
RepositoryModule::class,
SchedulersModule::class])
interface AppComponent{
/*
...
*/
@Named(NetworkModule.Interceptors.HEADER)
val headerInterceptor: Interceptor
}
这是一个模块,它提供了这个特殊的拦截器:
@Module
class NetworkModule {
object Interceptors {
const val HEADER = "HTTP_HEADER_INTERCEPTOR"
...
}
...
@Provides
@ApplicationScope
@Named(Interceptors.HEADER)
fun provideHeaderInterceptor(): Interceptor {
return HeaderInterceptor()
}
...
}
但是当我尝试创建我的“app”模块时出现问题(Build - > Make module'app')。 在制作它时,会发生错误,我无法弄清楚出了什么问题。
以下是错误的显示方式:
error: okhttp3.Interceptor cannot be provided without an @Provides-annotated method.
public abstract okhttp3.Interceptor getHeaderInterceptor();
okhttp3.Interceptor is provided at
com.example.app.di.components.AppComponent.getHeaderInterceptor()
答案 0 :(得分:1)
由于您注释了您的字段(val
)而不是Dagger想要使用的提供方法(getHeaderInterceptor
),因此会发生此错误。
您可以(应该)正确声明提供方法:
@Named(NetworkModule.Interceptors.HEADER)
fun provideHeaderInterceptor(): Interceptor
我不知道您使用val headerInterceptor
的方式或原因,但您也可以通过声明要在getter上使用的注释来修复它 < / p>
@get:Named(NetworkModule.Interceptors.HEADER")
val foo : Any
答案 1 :(得分:-3)
我使用匕首2提供改装。 制作网络模块..
@Module
public class NetModule { String baseUrl;
public NetModule(String baseUrl) {
this.baseUrl = baseUrl;
}
@Provides
@Singleton
OkHttpClient provideOkhttpClient(Context context) {
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient.Builder client = new OkHttpClient.Builder();
client.readTimeout(20, TimeUnit.SECONDS);
client.writeTimeout(20,TimeUnit.SECONDS);
client.connectTimeout(20, TimeUnit.SECONDS);
client.addInterceptor(interceptor);
client.addInterceptor(new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
if (context == null) {
request = request
.newBuilder()
.build();
} else {
request = request
.newBuilder()
.addHeader("Authorization", "Bearer " + AppSetting.getStringSharedPref(context, Constants.USER_KEY_TOKEN, ""))
.build();
}
return chain.proceed(request);
}
});
return client.build();
}
@Provides
@Singleton
Retrofit getRetrofit(){
return new Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create())
.baseUrl(baseUrl)
.client(provideOkhttpClient())
.build();
}
}
为api调用创建接口..
public interface Api {
@GET("marvel/")
Call<List<Hero>> getHero();
@GET("/users")
Call<List<User>> getUser(@Query("since") int since, @Query("per_page") int perPage);
}
为匕首2制作api组件。
@Singleton @Component(modules = {NetModule.class}) 公共接口ApiComponent { void injectApi(MainActivity activity); }
制作应用程序级别..
public class AppActivity extends Application {
private ApiComponent component;
@Override
public void onCreate() {
super.onCreate();
component = DaggerApiComponent.builder()
.netModule(new NetModule("https://api.github.com")).build();
}
public ApiComponent getComponent() {
return component;
}
}
在应用程序xml标记中的清单文件中定义此类..
android:name=".AppActivity"
然后将改装对象注入活动类后..
public class MainActivity extends AppCompatActivity {
private Button mBtnCallWs;
private ListView mLvData;
@Inject
Retrofit retrofit;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
((AppActivity)getApplication()).getComponent().injectApi(this);
initView();
}
private void initView() {
mBtnCallWs=findViewById(R.id.amBtnCall);
mLvData=findViewById(R.id.amLvData);
mBtnCallWs.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
getHeroes();
}
});
}
private void getHeroes() {
Api api = retrofit.create(Api.class);
Call<List<Hero>> call = api.getHero();
call.enqueue(new Callback<List<Hero>>() {
@Override
public void onResponse(Call<List<Hero>> call, Response<List<Hero>> response) {
List<Hero> heroList = response.body();
String[] heroes = new String[heroList.size()];
for (int i = 0; i < heroList.size(); i++) {
heroes[i] = heroList.get(i).getName();
}
mLvData.setAdapter(new ArrayAdapter<String>(getApplicationContext(), android.R.layout.simple_list_item_1, heroes));
}
@Override
public void onFailure(Call<List<Hero>> call, Throwable t) {
Toast.makeText(getApplicationContext(), t.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
}
上面的代码也提供了适配器绑定,您可以根据需要进行更改。