Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unsupported operation: Android, Retrofit, OkHttp. Adding interceptor in OkHttpClient

I am trying to add token based authentication via Retrofit 2.0-beta3 and OkHttpClient in Android using interceptors. But I get UnsupportedOperationException when I add my interceptor in OkHttpClient. Here is my code: In ApiClient.java

public static TrequantApiInterface getClient(final String token) {         if( sTreqantApiInterface == null) {              Log.v(RETROFIT_LOG, "Creating api client for the first time");             OkHttpClient okClient = new OkHttpClient();              okClient.interceptors().add(new Interceptor() {                 @Override                 public Response intercept(Interceptor.Chain chain) throws IOException {                     Request original = chain.request();                      // Request customization: add request headers                     Request.Builder requestBuilder = original.newBuilder()                             .header("Authorization", token)                             .method(original.method(), original.body());                      Request request = requestBuilder.build();                     return chain.proceed(request);                 }             });              Retrofit client = new Retrofit.Builder()                     .baseUrl(baseUrl)                     .client(okClient)                     .addConverterFactory(GsonConverterFactory.create())                     .build();             sTreqantApiInterface = client.create(TrequantApiInterface.class);         }         return sTreqantApiInterface;     } 

And I use it like:

private void ampFreqTest(){     String token = getSharedPreferences(getString(R.string.preference_file_key), Context.MODE_PRIVATE)                         .getString(getString(R.string.key_token), "");      service = ApiClient.getClient(token);     //I get an exception on this line:     Call<List<AmpFreq>> call = service.getUserAmpFreq("1");     call.enqueue(new Callback<List<AmpFreq>>() {         @Override         public void onResponse(Response<List<AmpFreq>> response) {             Toast.makeText(HomeScreen.this, "Got result", Toast.LENGTH_LONG);              Log.v(ApiClient.RETROFIT_LOG, "Success api client." + response.message());             Log.v(ApiClient.RETROFIT_LOG, "Success api client.");         }         @Override         public void onFailure(Throwable t) {             Toast.makeText(HomeScreen.this, t.getMessage() , Toast.LENGTH_LONG);             Log.v(ApiClient.RETROFIT_LOG, "Fail api client." + t.getMessage() );         }     }); } 

But I get this error:

Process: com.trequant.usman.trequant_android, PID: 14400 java.lang.UnsupportedOperationException at java.util.Collections$UnmodifiableCollection.add(Collections.java:932)  at com.trequant.usman.trequant_android.api.ApiClient.getClient(ApiClient.java:41) 

It gives me error on adding a new interceptor saying that it is not modifiableCollection but the documentation for interceptors() function says: /**

   * Returns a modifiable list of interceptors that observe the full span of each call: from before    * the connection is established (if any) until after the response source is selected (either the    * origin server, cache, or both).    */ 

What am I doing wrong? Could it be a bug?

like image 766
Usman khan Avatar asked Jan 08 '16 10:01

Usman khan


People also ask

How do I add an interceptor to OkHttpClient?

To actually make use of this interceptor, all we need to do is call the addInterceptor method when we build our OkHttpClient instance, and it should just work: OkHttpClient client = new OkHttpClient. Builder() . addInterceptor(new SimpleLoggingInterceptor()) .

Should I use okHTTP or retrofit?

You should use retrofit if you are trying to map your server API inside your application (type-safing). Retrofit is just an API adapter wrapped over okHTTP. If you want to type safe and modularise the interaction code with your API, use retrofit.

What is okHTTP interceptor in Android?

Interceptors, according to the documentation, are a powerful mechanism that can monitor, rewrite, and retry the API call. So, when we make an API call, we can either monitor it or perform some tasks. In a nutshell, Interceptors function similarly to airport security personnel during the security check process.

What version of okHTTP does retrofit use?

You can use 3.3. 1 version for now, just add dependency in your gradle file and set OkHttpClient to Retrofit instance.


1 Answers

This issue occurs when you change Retrofit 2.0-beta2 to Retrofit 2.0-beta3. You have to use builder if you want to create OkHttpClient object.

Change :

 OkHttpClient okClient = new OkHttpClient();   okClient.interceptors().add(new Interceptor() {        @Override        public Response intercept(Interceptor.Chain chain) throws IOException {             Request original = chain.request();              // Request customization: add request headers             Request.Builder requestBuilder = original.newBuilder()                     .header("Authorization", token)                     .method(original.method(), original.body());              Request request = requestBuilder.build();             return chain.proceed(request);         }  }); 

to :

 OkHttpClient okClient = new OkHttpClient.Builder()            .addInterceptor(                new Interceptor() {                  @Override                  public Response intercept(Interceptor.Chain chain) throws IOException {                        Request original = chain.request();                         // Request customization: add request headers                        Request.Builder requestBuilder = original.newBuilder()                                .header("Authorization", token)                                .method(original.method(), original.body());                         Request request = requestBuilder.build();                        return chain.proceed(request);                    }                })            .build(); 

It should resolve your problem.

like image 171
Konrad Krakowiak Avatar answered Sep 19 '22 16:09

Konrad Krakowiak