Retrofit Adding a tag to the source request object

I am trying to solve a problem when I create a couple of asynchronous calls and based on the original request, I complete the task. To solve this problem, I try to add a TAG for each request, and then on a successful response, I can get the tag and take action based on the tag. Here I use TAG only to identify the original request.

Problem

Before calling the enqueue method, I set the tag to the original request. But when I get the answer in a successful callback, I get another tag that I did not set. Somehow the request object itself comes as a tag object. I'm not sure how ???

Please read the code below.

GitHubService gitHubService = GitHubService.retrofit.create(GitHubService.class); final Call<List<Contributor>> call = gitHubService.repoContributors("square", "retrofit"); // Set the string tag to the original request object. call.request().newBuilder().tag("hello").build(); call.enqueue(new Callback<List<Contributor>>() { @Override public void onResponse(Call<List<Contributor>> call, Response<List<Contributor>> response) { Log.d("tag", response.raw().request().tag().toString()); // I'm getting Request{method=GET, url=https://api.github.com/repos/square/retrofit/contributors, tag=null} as the value of the tag. WHY???? final TextView textView = (TextView) findViewById(R.id.textView); textView.setText(response.body().toString()); } @Override public void onFailure(Call<List<Contributor>> call, Throwable t) { final TextView textView = (TextView) findViewById(R.id.textView); textView.setText("Something went wrong: " + t.getMessage()); } }); 

Can anyone point out what exactly I'm doing wrong here. Any help would be greatly appreciated.

+4
android retrofit2
source share
1 answer

This solution is clearly hacked, but it works.

Suppose you create your Retrofit service as follows:

  public <S> S createService(Class<S> serviceClass) { // Could be a simple "new" Retrofit.Builder retrofitBuilder = getRetrofitBuilder(baseUrl); // Could be a simple "new" OkHttpClient.Builder httpClientBuilder = getOkHttpClientBuilder(); // Build your OkHttp client OkHttpClient httpClient = httpClientBuilder.build(); Retrofit retrofit = retrofitBuilder.client(httpClient).build(); return retrofit.create(serviceClass); } 

You will need to add a new CallFactory to your Retrofit instance, so it adds a tag every time. Since the tag will be read-only, we will use an Object array containing only one element, which you can change later.

 Retrofit retrofit = retrofitBuilder.client(httpClient).callFactory(new Call.Factory() { @Override public Call newCall(Request request) { request = request.newBuilder().tag(new Object[]{null}).build(); Call call = httpClient.newCall(request); // We set the element to the call, to (at least) keep some consistency // If you want to only have Strings, create a String array and put the default value to null; ((Object[])request.tag())[0] = call; return call; } }).build(); 

Now, after making your call, you can change the contents of your tag:

 ((Object[])call.request().tag())[0] = "hello"; 
+3
source share

All Articles