What is the use of first (Call<T> call) Parameter in onResponse() and onFailure() method of Retrofit2

Viewed 1356

what is the use of call parameter here? how to use call parameter here? why is it there?

call.enqueue(new Callback<somePOJO>() {

        @Override
        public void onResponse(Call<somePOJO> call, Response<somePOJO> response){
        }

        @Override
        public void onFailure(Call<somePOJO> call, Throwable t) {

        }
2 Answers

Actually With Retrofit 2, onResponse is called even if there is a failure. i.e sometimes the call maybe successfull but data might be null for some reason. You can check whether response is successful by using response.isSuccessful() after getting data.

"call" in the response lets you call the same api again in case if failure.But that is not recommened because sometimes it may lead to loop in constant failure of api.

Dhiren, you really need to do some research before posting questions. This is a very simple question on a very widely used library. There are a lot of examples showing the use of it. Please check the following link which explains the use of Retrofit2 Library and what is the need of Call class.

Getting started with Retrofit 2

Below is a content for your reference from the same link.

Retrofit 2 is a type-safe HTTP client for Android (and Java), but first of all, it’s a library, so to use it we need to declare the correct dependencies. That is easy, however, note that we need to depend explicitly on the gson converter to transform the JSON responses to the model classes. It wasn’t the case with Retrofit 1, so be careful.

Add these two lines to the build.gradle file:

compile 'com.squareup.retrofit2:retrofit:2.0.2'
compile 'com.squareup.retrofit2:converter-gson:2.0.2'

Then, given that we want our application to access the network we need to declare the INTERNET permission in the Android manifest file. This is pretty straightforward, just add this line to the app/src/main/AndroidManifest.xml file:

<uses-permission android:name="android.permission.INTERNET" />

With these preliminary tasks out of the way, we can look at the actual code. The main idea behind Retrofit is that it’s possible to generate the code to query HTTP services at runtime, requiring the developer to produce just an interface as the “specification.” Imagine we have the following model class:

public class Contributor {

    String login;
    String html_url;

    int contributions;

    @Override
    public String toString() {
        return login + " (" + contributions + ")";
    }
}

From this we can create the GithubService interface that will embody our HTTP communication.

public interface GitHubService {
  @GET(“repos/{owner}/{repo}/contributors”)
  Call<List<Contributor>> repoContributors(
      @Path(“owner”) String owner,
      @Path(“repo”) String repo);
}

This is the simplest example, we add the @GET annotation on an interface method and provide the path part of the URL that we want to expose it on. Conveniently, the method parameters can be referenced in the path string so you won’t need to jump through hoops to set those. Additionally, with other annotations you can specify query parameters, POST request body and so on:

  • @Query(“key”) — for GET request query parameter
  • @QueryMap — for the map of parameters
  • @Body — use it with the @POST annotation to provide the query body content.
  • Now, to use this interface during runtime, we’ll need to build a Retrofit object:

    interface GitHubService {
        @GET("repos/{owner}/{repo}/contributors")
        Call<List<Contributor>> repoContributors(
                @Path("owner") String owner,
                @Path("repo") String repo);
    
    
        public static final Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("https://api.github.com/")
                .addConverterFactory(GsonConverterFactory.create())
                .build();
    }
    

    I like to use the Retrofit builder in the same interface that contains the queries to the website. This way I’m not tempted to complicate things beyond measure. Yeah, there’s some general configuration in use here. We provide the default converter factory to turn the JSON response objects into Java objects, but it’s better to copy-paste that into every service class you have rather than use a single abstraction only to find out it’s leaking.

    With these pieces in place, we just need to perform the network call:

  • the specification of our queries
  • the Retrofit object builder
  • To create the implementation of the GitHubService interface, instantiate a Call object for the HTTP query which we want to perform and execute the request.

    GitHubService gitHubService = GitHubService.retrofit.create(GitHubService.class);
    Call<List<Contributor>> call = gitHubService.repoContributors(“square”, “retrofit”);
    List<Contributor> result = call.execute().body();
    

    Alternatively, one might choose to schedule the call to happen asynchronously and provide the callback to be executed upon completion.

    call.enqueue(new Callback<List<Contributor>>() {
      @Override
      public void onResponse(Response<List<Contributor>> response, Retrofit retrofit) {
        // handle success
      }
    
      @Override
      public void onFailure(Throwable t) {
        // handle failure
      }
    });
    

    Sounds simple enough! Let’s prepare some sort of UI and wire the code in. Following the floating button app template design, we need to change the content_main.xml file. Here’s my take on adding a button to initiate the query and a text area to show the results:

    <Button
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="Fetch"
      android:id="@+id/button"
      android:layout_alignParentBottom="true"
      android:layout_centerHorizontal="true"
      android:layout_marginBottom="151dp" />
    
    <TextView
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:textAppearance="?android:attr/textAppearanceLarge"
      android:text=""
      android:id="@+id/textView"
      android:layout_above="@+id/button"
      android:layout_alignParentEnd="true"
      android:layout_alignParentStart="true"
      android:layout_alignParentTop="true"
      android:textIsSelectable="false" />
    

    Here’s how the network call code might look on your first try:

    Button button = (Button) findViewById(R.id.button);
    button.setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View view) {
        GitHubService gitHubService = GitHubService.retrofit.create(GitHubService.class);
        Call<List<Contributor>> call = gitHubService.repoContributors(“square”, “retrofit”);
        String result = call.execute().body().toString();
        TextView textView = (TextView) findViewById(R.id.textView);
        textView.setText(result);
      }
    });
    <p>Naturally, t
    

    his code won’t work; the Android framework won’t allow you to perform network calls on the UI thread. The UI thread should only handle input from the user. Performing any long blocking operations on this thread will simply make the user experience sluggish.

    So, we need to refactor this code by moving the network call to a background thread. With JRebel for Android, this won’t take any time at all. Let’s refactor it to use the enqueue method we looked at above.
    Now the code looks like the snippet below and works too:

    Button button = (Button) findViewById(R.id.button);
    button.setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View view) {
        GitHubService gitHubService = GitHubService.retrofit.create(GitHubService.class);
        final Call<List<Contributor>> call =
                gitHubService.repoContributors("square", "retrofit");
    
        call.enqueue(new Callback<List<Contributor>>() {
            @Override
            public void onResponse(Call<List<Contributor>> call, Response<List<Contributor>> response) {
                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());
            }
        });
      }
    });
    

    That’s it, the code now runs, the text view get’s updated with the result of out HTTP query.

    The skeleton app is ready, the code builds and works. Now you are equipped to play with both Retrofit and JRebel for Android. You can change a line of code here and there and see the results of your new code in the running app, without any time-wasting. Try adding a couple of fields to the Contributor class. Replace the text view with a list of proper widgets for every contributor. Change the HTTP endpoint altogether and query another website.

    Related