We have used Volley as networking library in lot of my articles. Today we are going to look at another awesome library Retrofit to make the http calls. Retrofit is denitely the better alternative to volley in terms of ease of use, performance, extensibility and other things. It is a type-­safe REST client for Android built by Square. Using this tool android developer can make all network stuff much more easier. As an example, we are going to download some json and show it in RecyclerView as a list.

android-working-with-retrofit-http-library-example

Here is the final app we are about to build.

android-working-with-retrofit-http-library

Getting TMDB API Key / Sample JSON

For this tutorial we will use The TMDb API. In order to use this API it is necessary to obtain the API key. Here you can take a look how to obtain the API key. In short, you need to register and login in order to obtain the key.

After this it should looks like this

android-obtaining-tmdb-api-key

1. Creating New Project

android-working-with-retrofit

1. Create a new project in Android Studio from File ⇒ New Project. When it prompts you to select the default activity, select Empty Activity and proceed.

2. Open build.gradle and add Retrofit, Gson dependencies.

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:23.3.0'

    // retrofit, gson
    compile 'com.google.code.gson:gson:2.6.2'
    compile 'com.squareup.retrofit2:retrofit:2.0.2'
    compile 'com.squareup.retrofit2:converter-gson:2.0.2'
}

3. Since we are working with network operations we need to add INTERNET permissions in AndroidManifest.xml file

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="info.androidhive.retrofit">

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

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".activity.MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>

4. Create four sub packages named activity, adapter, rest and model in your main package. Move your MainActivity under activity package.

2. Creating Model Class

5. First, we need to know what type of JSON response we will be receiving. The following example uses The TMDb API as an example and show how to create Java objects that will be able to parse the latest movies. Based on the JSON response returned for this API call, let’s first define how a basic movie representation should look like:

Using this route (http://api.themoviedb.org/3/movie/top_rated?api_key=INSERT_YOUR_API_KEY) we can get the last 50 movies. Let’s insert it into browser and see. Using JsonViewer you can see JSON in more structured way. Copy the response from browser to this JsonViewer and this online tool show JSON like here:

android-retrofit-json-viewer

6. Create a class named Movie.java under model package.

package info.androidhive.retrofit.model;

import com.google.gson.annotations.SerializedName;

import java.util.ArrayList;
import java.util.List;


public class Movie {
    @SerializedName("poster_path")
    private String posterPath;
    @SerializedName("adult")
    private boolean adult;
    @SerializedName("overview")
    private String overview;
    @SerializedName("release_date")
    private String releaseDate;
    @SerializedName("genre_ids")
    private List<Integer> genreIds = new ArrayList<Integer>();
    @SerializedName("id")
    private Integer id;
    @SerializedName("original_title")
    private String originalTitle;
    @SerializedName("original_language")
    private String originalLanguage;
    @SerializedName("title")
    private String title;
    @SerializedName("backdrop_path")
    private String backdropPath;
    @SerializedName("popularity")
    private Double popularity;
    @SerializedName("vote_count")
    private Integer voteCount;
    @SerializedName("video")
    private Boolean video;
    @SerializedName("vote_average")
    private Double voteAverage;

    public Movie(String posterPath, boolean adult, String overview, String releaseDate, List<Integer> genreIds, Integer id,
                 String originalTitle, String originalLanguage, String title, String backdropPath, Double popularity,
                 Integer voteCount, Boolean video, Double voteAverage) {
        this.posterPath = posterPath;
        this.adult = adult;
        this.overview = overview;
        this.releaseDate = releaseDate;
        this.genreIds = genreIds;
        this.id = id;
        this.originalTitle = originalTitle;
        this.originalLanguage = originalLanguage;
        this.title = title;
        this.backdropPath = backdropPath;
        this.popularity = popularity;
        this.voteCount = voteCount;
        this.video = video;
        this.voteAverage = voteAverage;
    }

    public String getPosterPath() {
        return posterPath;
    }

    public void setPosterPath(String posterPath) {
        this.posterPath = posterPath;
    }

    public boolean isAdult() {
        return adult;
    }

    public void setAdult(boolean adult) {
        this.adult = adult;
    }

    public String getOverview() {
        return overview;
    }

    public void setOverview(String overview) {
        this.overview = overview;
    }

    public String getReleaseDate() {
        return releaseDate;
    }

    public void setReleaseDate(String releaseDate) {
        this.releaseDate = releaseDate;
    }

    public List<Integer> getGenreIds() {
        return genreIds;
    }

    public void setGenreIds(List<Integer> genreIds) {
        this.genreIds = genreIds;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getOriginalTitle() {
        return originalTitle;
    }

    public void setOriginalTitle(String originalTitle) {
        this.originalTitle = originalTitle;
    }

    public String getOriginalLanguage() {
        return originalLanguage;
    }

    public void setOriginalLanguage(String originalLanguage) {
        this.originalLanguage = originalLanguage;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getBackdropPath() {
        return backdropPath;
    }

    public void setBackdropPath(String backdropPath) {
        this.backdropPath = backdropPath;
    }

    public Double getPopularity() {
        return popularity;
    }

    public void setPopularity(Double popularity) {
        this.popularity = popularity;
    }

    public Integer getVoteCount() {
        return voteCount;
    }

    public void setVoteCount(Integer voteCount) {
        this.voteCount = voteCount;
    }

    public Boolean getVideo() {
        return video;
    }

    public void setVideo(Boolean video) {
        this.video = video;
    }

    public Double getVoteAverage() {
        return voteAverage;
    }

    public void setVoteAverage(Double voteAverage) {
        this.voteAverage = voteAverage;
    }
}

7. Also we need to create MovieResponse.java class, since we have some extra fields like page number. This class contains all fetched movies and extra information. Create MovieResponse.java under model package.

package info.androidhive.retrofit.model;

import com.google.gson.annotations.SerializedName;

import java.util.List;


public class MoviesResponse {
    @SerializedName("page")
    private int page;
    @SerializedName("results")
    private List<Movie> results;
    @SerializedName("total_results")
    private int totalResults;
    @SerializedName("total_pages")
    private int totalPages;

    public int getPage() {
        return page;
    }

    public void setPage(int page) {
        this.page = page;
    }

    public List<Movie> getResults() {
        return results;
    }

    public void setResults(List<Movie> results) {
        this.results = results;
    }

    public int getTotalResults() {
        return totalResults;
    }

    public void setTotalResults(int totalResults) {
        this.totalResults = totalResults;
    }

    public int getTotalPages() {
        return totalPages;
    }

    public void setTotalPages(int totalPages) {
        this.totalPages = totalPages;
    }
}

3. Creating the Retrofit instance

8. To send network requests to an API, we need to use the Retrofit Builder class and specify the base URL for the service. So, create a class named ApiClient.java under rest package.

Here BASE_URL – it is basic URL of our API. We will use this URL for all requests later.

package info.androidhive.retrofit.rest;

import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;


public class ApiClient {

    public static final String BASE_URL = "http://api.themoviedb.org/3/";
    private static Retrofit retrofit = null;


    public static Retrofit getClient() {
        if (retrofit==null) {
            retrofit = new Retrofit.Builder()
                    .baseUrl(BASE_URL)
                    .addConverterFactory(GsonConverterFactory.create())
                    .build();
        }
        return retrofit;
    }
}

4. Define the Endpoints

The endpoints are defined inside of an interface using special retrofit annotations to encode details about the parameters and request method. In addition, the return value is always a parameterized Call<T> object such as Call<MovieResponse>. For instance, the interface defines each endpoint in the following way.

9. Create ApiInterface.java under rest package.

package info.androidhive.retrofit.rest;

import info.androidhive.retrofit.model.MoviesResponse;
import retrofit2.Call;
import retrofit2.http.GET;
import retrofit2.http.Path;
import retrofit2.http.Query;


public interface ApiInterface {
    @GET("movie/top_rated")
    Call<MoviesResponse> getTopRatedMovies(@Query("api_key") String apiKey);

    @GET("movie/{id}")
    Call<MoviesResponse> getMovieDetails(@Path("id") int id, @Query("api_key") String apiKey);
}

So, using this route the retrofit will generate the following URL:
http://api.themoviedb.org/3/movie/top_rated?api_key=12345678910111213

Each endpoint specifies an annotation of the HTTP method (GET, POST, etc.) and the parameters of this method can also have special annotations (@Query, @Path, @Body etc.)

Take a look to other annotations:

@Path – variable substitution for the API endpoint. For example movie id will be swapped for{id} in the URL endpoint.

@Query – specifies the query key name with the value of the annotated parameter.

@Body – payload for the POST call

@Header – specifies the header with the value of the annotated parameter

5. Making the First Request

10. Let’s make the first request from our MainActivity. If we want to consume the API asynchronously, we call the service as follows. Open the MainActivity.java and do the below changes.

Make sure that you replaced API_KEY with yours.

public class MainActivity extends AppCompatActivity {
    private static final String TAG = MainActivity.class.getSimpleName();

    // TODO - insert your themoviedb.org API KEY here
    private final static String API_KEY = "";


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        if (API_KEY.isEmpty()) {
            Toast.makeText(getApplicationContext(), "Please obtain your API KEY first from themoviedb.org", Toast.LENGTH_LONG).show();
            return;
        }

        ApiInterface apiService =
                ApiClient.getClient().create(ApiInterface.class);

        Call<MoviesResponse> call = apiService.getTopRatedMovies(API_KEY);
        call.enqueue(new Callback<MoviesResponse>() {
            @Override
            public void onResponse(Call<MoviesResponse>call, Response<MoviesResponse> response) {
                List<Movie> movies = response.body().getResults();
                Log.d(TAG, "Number of movies received: " + movies.size());
            }

            @Override
            public void onFailure(Call<MoviesResponse>call, Throwable t) {
                // Log error here since request failed
                Log.e(TAG, t.toString());
            }
        });
    }
}

Retrofit will download and parse the API data on a background thread, and then return the results back to the UI thread via the onResponse or onFailure method.

Congratulations! We have created our first rest client. Let’s create some UI in order to see our results.

6. Displaying the Results in RecyclerView

11. Let’s create ListView for fetched results. We will use RecyclerView for it. First of all, add it to the gradle.gradle

dependencies {
    .
    .

    // recycler view
    compile 'com.android.support:recyclerview-v7:23.3.0'
}

In order to show fetched items we need to create layout, which will show all data. We need 4 TextView and 1 ImageView for star image.

12. Open colors.xml and add the below color values.

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="colorPrimary">#3F51B5</color>
    <color name="colorPrimaryDark">#303F9F</color>
    <color name="colorAccent">#FF4081</color>

    <color name="orange">#FF3909</color>
    <color name="colorAccentDark">#00B482</color>

    <color name="colorBlack">#555555</color>
    <color name="colorWhite">#FFFFFF</color>
    <color name="colorGrey">#707070</color>
    <color name="colorGreyLight">#8A8A8A</color>
</resources>

13. Create a layout named star.xml under res drawable with the below content.

<!-- drawable/star.xml -->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="24dp"
    android:height="24dp"
    android:viewportHeight="24"
    android:viewportWidth="24">
    <path
        android:fillColor="#000"
        android:pathData="M12,17.27L18.18,21L16.54,13.97L22,9.24L14.81,8.62L12,2L9.19,8.62L2,9.24L7.45,13.97L5.82,21L12,17.27Z" />
</vector>

14. Create a layout named list_item_movie.java under res layout.

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/movies_layout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:gravity="center_vertical"
    android:minHeight="72dp"
    android:orientation="horizontal"
    android:padding="16dp">

    <LinearLayout
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:orientation="vertical">

        <TextView
            android:id="@+id/title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="top"
            android:paddingRight="16dp"
            android:textStyle="bold"
            android:textColor="@color/colorBlack"
            android:textSize="16sp" />


        <TextView
            android:id="@+id/subtitle"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:paddingRight="16dp"
            android:textColor="@color/colorGreyLight" />

        <TextView
            android:id="@+id/description"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:maxLines="3"
            android:paddingRight="16dp"
            android:textColor="@color/colorGreyLight" />

    </LinearLayout>

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="35dp"
        android:orientation="horizontal">

        <ImageView
            android:id="@+id/rating_image"
            android:layout_width="15dp"
            android:layout_height="15dp"
            android:layout_centerInParent="true"
            android:scaleType="centerCrop"
            android:src="@drawable/star"
            android:tint="@color/colorAccent" />


        <TextView
            android:id="@+id/rating"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="8dp"
            android:text="5.0" />
    </LinearLayout>

</LinearLayout>

15. Adapter is a common pattern which helps to bind view and data, so let’s implement adapter for this. Create a class named MoviesAdapter.java under adapter package.

package info.androidhive.retrofit.adapter;

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;

import java.util.List;

import info.androidhive.retrofit.R;
import info.androidhive.retrofit.model.Movie;

public class MoviesAdapter extends RecyclerView.Adapter<MoviesAdapter.MovieViewHolder> {

    private List<Movie> movies;
    private int rowLayout;
    private Context context;


    public static class MovieViewHolder extends RecyclerView.ViewHolder {
        LinearLayout moviesLayout;
        TextView movieTitle;
        TextView data;
        TextView movieDescription;
        TextView rating;


        public MovieViewHolder(View v) {
            super(v);
            moviesLayout = (LinearLayout) v.findViewById(R.id.movies_layout);
            movieTitle = (TextView) v.findViewById(R.id.title);
            data = (TextView) v.findViewById(R.id.subtitle);
            movieDescription = (TextView) v.findViewById(R.id.description);
            rating = (TextView) v.findViewById(R.id.rating);
        }
    }

    public MoviesAdapter(List<Movie> movies, int rowLayout, Context context) {
        this.movies = movies;
        this.rowLayout = rowLayout;
        this.context = context;
    }

    @Override
    public MoviesAdapter.MovieViewHolder onCreateViewHolder(ViewGroup parent,
                                                            int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(rowLayout, parent, false);
        return new MovieViewHolder(view);
    }


    @Override
    public void onBindViewHolder(MovieViewHolder holder, final int position) {
        holder.movieTitle.setText(movies.get(position).getTitle());
        holder.data.setText(movies.get(position).getReleaseDate());
        holder.movieDescription.setText(movies.get(position).getOverview());
        holder.rating.setText(movies.get(position).getVoteAverage().toString());
    }

    @Override
    public int getItemCount() {
        return movies.size();
    }
}

16. Open MainActivity.java and modify the code as below.

package info.androidhive.retrofit.activity;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.widget.Toast;

import java.util.List;

import info.androidhive.retrofit.R;
import info.androidhive.retrofit.adapter.MoviesAdapter;
import info.androidhive.retrofit.model.Movie;
import info.androidhive.retrofit.model.MoviesResponse;
import info.androidhive.retrofit.rest.ApiClient;
import info.androidhive.retrofit.rest.ApiInterface;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

public class MainActivity extends AppCompatActivity {

    private static final String TAG = MainActivity.class.getSimpleName();


    // TODO - insert your themoviedb.org API KEY here
    private final static String API_KEY = "";


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        if (API_KEY.isEmpty()) {
            Toast.makeText(getApplicationContext(), "Please obtain your API KEY from themoviedb.org first!", Toast.LENGTH_LONG).show();
            return;
        }

        final RecyclerView recyclerView = (RecyclerView) findViewById(R.id.movies_recycler_view);
        recyclerView.setLayoutManager(new LinearLayoutManager(this));

        ApiInterface apiService =
                ApiClient.getClient().create(ApiInterface.class);

        Call<MoviesResponse> call = apiService.getTopRatedMovies(API_KEY);
        call.enqueue(new Callback<MoviesResponse>() {
            @Override
            public void onResponse(Call<MoviesResponse> call, Response<MoviesResponse> response) {
                int statusCode = response.code();
                List<Movie> movies = response.body().getResults();
                recyclerView.setAdapter(new MoviesAdapter(movies, R.layout.list_item_movie, getApplicationContext()));
            }

            @Override
            public void onFailure(Call<MoviesResponse> call, Throwable t) {
                // Log error here since request failed
                Log.e(TAG, t.toString());
            }
        });
    }
}

Run the app and we get this nice list

android-working-with-retrofit-http-library

To sum it up, Retrofit is one of the best tool for working with network requests. I have considered most common cases which can be helpful in your projects. Happy coding!

Ravi is hardcore Android programmer and Android programming has been his passion since he compiled his first hello-world program. Solving real problems of Android developers through tutorials has always been interesting part for him.
  • varuki

    Thanks for the tutorial

  • This one is for Retrofit 2.0 ?

    • Htoo Aung Hlaing

      Yes, sure.In Retrofit 2.0, we will need json converter as an extra dependency.

  • Hossein

    Thanks for the tutorial
    woocommerce & wordpress native android app tutorial Please

  • Awesome , will execute and Let you know !!

    • Siranjeevi

      Hi is that getMovieDetails working now?
      Can you able to get movieDetail json object?

      • Yes , it works , but you’ll have to make minor changes
        @GET(“movie/{id}”)
        Call getMovieDetails(@Path(“id”) int id, @Query(“api_key”) String apiKey);
        to
        @GET(“movie/{id}”)
        Call getMovieDetails(@Path(“id”) int id, @Query(“api_key”) String apiKey);

        and then use it accordingly !

        • shashi patil

          hi rakhi can u teach me how to highlight filtered string in listview… i have done of filter but highlight is pending…. patilshashi43@gmail.com please mail me

  • woocommerce & wordpress native android app tutorial Please.

  • Htoo Aung Hlaing

    Hi Ravi, need to fix in heading 6. Displaying the Results in RecyclerView , for “gradle.gradle” to “build.gradle”.

  • Htoo Aung Hlaing

    Thanks Ravi, for your awesome tutorial .

  • Jojo

    Hi Ravi, I am using OKHTTP for my projects, Can you please give me an advice for library choice for http calls?
    Which one is better.?
    1. OKHTTP
    2. Retrofit
    3. Volly
    I have a big list of Data with Images get from Azure. help me.

  • Thanks

  • Sandeep Bhambad

    Thanks for the Tutorial. Can you please also add retrofit2 with rx and dagger 2?

  • Nam

    I have json string
    {
    “type”: “s”,
    “version”: “1.0”,
    “data”: {
    “name1”: { “id”:”5″, “title”:”abcxyz” },
    “name2”: {“id”:”8″, “title”:”lalalal”},
    “name3”: {“id”:”3″, “title”:”abc”},
    “name4”: {“id”:”10″, “title”:”bloblal”},
    “name5”: {“id”:”11″, “title”:”no”},
    … and go to “name150”
    (have 150 json Object in Object “data”)
    }

    In Model package, i don’t know how to create class
    (create class with name1, name2, name3, … name150) i don’t think so. Help me.
    I don’t develop json Respone. so i don’t know how to fix.
    Thx!

  • truth

    Hi bro ! I can recommend you to use lombok library which will produce all your getter, setter, and constructors at runtime. Also builder pattern is done with lombok. Your model classes will be so much clear 🙂

  • Mezooo

    ooooooooh you really you are best programmer in the world thank you so much Mr.Ravi

    but Finally I have a Big problem all android Developers dropped in it.

    This Problem is Design Pattern for android (MVC Pattern) I am confusing about how can i use it. perfectly I see Some library handle this issue but i don’t know which one better and which one the best practices.

    I hope to make a tutorial for best MVC pattern it’s so important for fast and accuracy and stable coding

    This is one of Library handle this problem

    https://github.com/kejunxia/AndroidMvc

    but i want you advice and how can i use it for big projects with calling back-en and update view and handle all controllers with some advance patterns like observer pattern.

    • Thanks Mezooo for your suggestion. I strongly look into best solution for it.

  • tohin

    Why app is crassing Caused by: java.lang.IllegalArgumentException: baseUrl must end in /:
    anybody help me plz

  • Bob

    What is info.androidhive.retrofit.R? It pops up in the main activity and the adapter but I dont see what it’s trying to import.

    • It’s your projects package name. In Android Studio, goto Build -> Clean Project. The .R file will be generated each time you change something in your project.

  • tohin

    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.eliteappsbd.retrofitexm/com.eliteappsbd.retrofitexm.activity.MainActivity}: java.lang.IllegalArgumentException: baseUrl must end in /: https://api.themoviedb.org//3//movie//550?api_key=a2f888b27315e62e471b2d587048f32e//
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2455)

    Caused by: java.lang.IllegalArgumentException: baseUrl must end in /: https://api.themoviedb.org//3//movie//550?api_key=a2f888b27315e62e471b2d587048f32e//
    at retrofit2.Retrofit$Builder.baseUrl(Retrofit.java:496)
    at retrofit2.Retrofit$Builder.baseUrl(Retrofit.java:439)
    at com.eliteappsbd.retrofitexm.rest.ApiClient.getClient(ApiClient.java:16)
    at com.eliteappsbd.retrofitexm.activity.MainActivity.onCreate(MainActivity.java:44)

    Please help me

  • tohin

    Caused by: java.lang.IllegalArgumentException: baseUrl must end in /: https://api.themoviedb.org/3/movie/550?api_key=a2f888b27315e62e471b2d587048f32e
    at retrofit2.Retrofit$Builder.baseUrl(Retrofit.java:496)
    at retrofit2.Retrofit$Builder.baseUrl(Retrofit.java:439)
    at com.eliteappsbd.retrofitexm.rest.ApiClient.getClient(ApiClient.java:16)
    at com.eliteappsbd.retrofitexm.activity.MainActivity.onCreate(MainActivity.java:44)

  • Rishabh

    Any idea, how to get more and more movies on the list? It just stops after 20 results. How do i push the request to get more results?

  • VARUN BEHL

    Great tutorial . Can you also add for making multiple HTTP request using retrofit.

  • Arslanali

    Hi Ravi, how to send POST request?
    Im need to autorization in server. Server response JSON(user data)

    {

    “error”: false,
    “message”: “suc”,
    “token”: “2d60d05de0a39428c3d6a6cd33d230aa”,
    “fio”: ” Arslanali”,
    “phone”: “7”,
    “myСhief”: “my”
    }

  • Htoo Aung Hlaing

    Hi Ravi, I ‘m able to file download with Retrofit, but i have to update UI for download process, Retrofit is not OK for that now, How can I handle to Update with Retrofit?

  • Bagus Aji

    final RecyclerView recyclerView = (RecyclerView) findViewById(R.id.movies_recycler_view);

    Where’s the id movies_recycler_view?

    • Đỗ Gia Long

      in activity_main.xml

    • Lucian Iacob

      You have to declare an recycler view inside activity_main.xml

  • Nikhil Katekhaye

    Can we take response in String rather than in POJO class using Retrofit 2.0

  • vxcvxv

    Its Great

  • Eunan

    Great Tut, Can you do a tut on how to use this library to parse XML very little stuff online about parsing XML with retrofit.

  • chemechaos

    I’m trying to do this in a fragment but I’m stuck at this line:

    ApiInterface apiService =ApiClient.getClient().create(ApiInterface.class);

    I haven’t been able to find any way around it, please help anyone? I get “unreachable statement”

    Also I got stuck a long time on the ApiInterface because I was trying to create the POST without having the model first. As soon as you create the POST, GET you should make the Call sendSomething etc. to avoid the error.

    Edit: So far it worked. I was putting the code into oncreateview and now changed it to onviewcreated

  • venkat1017

    Thanks ravi but can we use both volley and retrofit at the same time ?– http://www.androidxu.com

  • Chandrahasan

    Great tutorial Thanks, Can you create same retrofit 2 with post examples like image upload and etc

  • Hello Ravi, really great tutorial.
    As @Chandrahasan I would also like to request you a tutorial on retrofit 2 with Post, Headers and multipart request also

  • Nimzy Kevin Maina

    Hi Ravi, Good work you are doing here. You deserve a gold medal!!

    I would like to add to @rivu_chk:disqus’s and @Chandrahasan’s requests. Please add the following to part 2 of the tutorial.

    1. CRUD operations.

    2. Handling json error response from within the public void failure(){…} method and displaying it to the user.(not just logging the error). I have seen several tutorials which do so on the success method..
    This requires that the api return a status code of 200 every time but containing the error json response. My api returns actual [400,404,422] responses. Please help with this as i have tried everything but to no avail.

    3. Image handling using glide (in collaboration with retrofit)

    Thanks in advance

    • Hi Nimzy

      Thanks you for suggestions. I’ll try to update the article, but not very soon as I am working on other articles.

  • Dexter

    Hi Ravi great article! I was wondering for for getmovieDetails with movie/id which returns a different json , we wouldn’t be able to use it with MoviesResponse . So what change do we need to make inorder to parse and get data from the json which doesn’t have “results” , it is simply plain body . Please check http://api.themoviedb.org/3/movie/246655?api_key=API_KEY.

    Thanks

  • SelvaGanesh

    Great tutorial Thanks, Can you create same retrofit 2 with post method example.

  • nitish patel

    Hi Ravi, Awesome article. I was getting following 2 exception while requesting my api. 1.java.lang.ExceptionInInitializerError
    2. java.lang.NoClassDefFoundError: okhttp3.internal.Util. I had lot of search but not able to get proper answer can you help me to resolve? I was used to with retrofit 1.9 but this 2.+ all versions I found this 2 exception.

    • I am too not sure about these errors. Even I need to search Did you able to run the downloaded project I have given?

      • nitish patel

        Yes. I have downloaded it. It works fine. Even my application with retrofit 2 works fine but when I add google pay service dependency and run I get this two exceptions. Is it like that google play service have some problem with OKHTTP3 library?

        • Can you give me the exception?

          • nitish patel

            07-09 11:10:59.769 7425-7425/com.example.plugshare E/AndroidRuntime: FATAL EXCEPTION: main
            java.lang.ExceptionInInitializerError
            at com.example.plugshare.MainActivity.getOpenChargingStation(MainActivity.java:27)
            at com.example.plugshare.MainActivity.onCreate(MainActivity.java:22)
            at android.app.Activity.performCreate(Activity.java:5203)
            at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1094)
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2078)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2139)
            at android.app.ActivityThread.access$700(ActivityThread.java:143)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1241)
            at android.os.Handler.dispatchMessage(Handler.java:99)
            at android.os.Looper.loop(Looper.java:137)
            at android.app.ActivityThread.main(ActivityThread.java:4960)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:511)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1038)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:805)
            at dalvik.system.NativeStart.main(Native Method)
            Caused by: java.lang.ExceptionInInitializerError
            at okhttp3.OkHttpClient$Builder.(OkHttpClient.java:359)
            at com.example.plugshare.ServiceGenerator.(ServiceGenerator.java:35)
            at com.example.plugshare.MainActivity.getOpenChargingStation(MainActivity.java:27)
            at com.example.plugshare.MainActivity.onCreate(MainActivity.java:22)
            at android.app.Activity.performCreate(Activity.java:5203)
            at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1094)
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2078)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2139)
            at android.app.ActivityThread.access$700(ActivityThread.java:143)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1241)
            at android.os.Handler.dispatchMessage(Handler.java:99)
            at android.os.Looper.loop(Looper.java:137)
            at android.app.ActivityThread.main(ActivityThread.java:4960)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:511)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1038)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:805)
            at dalvik.system.NativeStart.main(Native Method)
            Caused by: java.lang.NoClassDefFoundError: okhttp3.internal.Util
            at okhttp3.OkHttpClient.(OkHttpClient.java:61)
            at okhttp3.OkHttpClient$Builder.(OkHttpClient.java:359)
            at com.example.plugshare.ServiceGenerator.(ServiceGenerator.java:35)
            at com.example.plugshare.MainActivity.getOpenChargingStation(MainActivity.java:27)
            at com.example.plugshare.MainActivity.onCreate(MainActivity.java:22)
            at android.app.Activity.performCreate(Activity.java:5203)
            at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1094)
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2078)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2139)
            at android.app.ActivityThread.access$700(ActivityThread.java:143)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1241)
            at android.os.Handler.dispatchMessage(Handler.java:99)
            at android.os.Looper.loop(Looper.java:137)
            at android.app.ActivityThread.main(ActivityThread.java:4960)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:511)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1038)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:805)
            at dalvik.system.NativeStart.main(Native Method)

          • nitish patel
          • nitish patel
          • nitish patel

            FATAL EXCEPTION: main
            java.lang.ExceptionInInitializerError
            at com.example.plugshare.MainActivity.getOpenChargingStation(MainActivity.java:27)
            at com.example.plugshare.MainActivity.onCreate(MainActivity.java:22)
            at android.app.Activity.performCreate(Activity.java:5203)
            at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1094)
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2078)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2139)
            at android.app.ActivityThread.access$700(ActivityThread.java:143)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1241)
            at android.os.Handler.dispatchMessage(Handler.java:99)
            at android.os.Looper.loop(Looper.java:137)
            at android.app.ActivityThread.main(ActivityThread.java:4960)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:511)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1038)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:805)
            at dalvik.system.NativeStart.main(Native Method)
            Caused by: java.lang.ExceptionInInitializerError
            at okhttp3.OkHttpClient$Builder.(OkHttpClient.java:359)
            at com.example.plugshare.ServiceGenerator.(ServiceGenerator.java:35)
            at com.example.plugshare.MainActivity.getOpenChargingStation(MainActivity.java:27)
            at com.example.plugshare.MainActivity.onCreate(MainActivity.java:22)
            at android.app.Activity.performCreate(Activity.java:5203)
            at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1094)
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2078)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2139)
            at android.app.ActivityThread.access$700(ActivityThread.java:143)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1241)
            at android.os.Handler.dispatchMessage(Handler.java:99)
            at android.os.Looper.loop(Looper.java:137)
            at android.app.ActivityThread.main(ActivityThread.java:4960)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:511)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1038)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:805)
            at dalvik.system.NativeStart.main(Native Method)
            Caused by: java.lang.NoClassDefFoundError: okhttp3.internal.Util
            at okhttp3.OkHttpClient.(OkHttpClient.java:61)
            at okhttp3.OkHttpClient$Builder.(OkHttpClient.java:359)
            at com.example.plugshare.ServiceGenerator.(ServiceGenerator.java:35)
            at com.example.plugshare.MainActivity.getOpenChargingStation(MainActivity.java:27)
            at com.example.plugshare.MainActivity.onCreate(MainActivity.java:22)
            at android.app.Activity.performCreate(Activity.java:5203)
            at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1094)
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2078)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2139)
            at android.app.ActivityThread.access$700(ActivityThread.java:143)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1241)
            at android.os.Handler.dispatchMessage(Handler.java:99)
            at android.os.Looper.loop(Looper.java:137)
            at android.app.ActivityThread.main(ActivityThread.java:4960)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:511)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1038)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:805)
            at dalvik.system.NativeStart.main(Native Method)

          • jagdish Gupta

            Adding this two jars worked for me…
            compile files(‘libs/okhttp-3.4.1.jar’)
            compile files(‘libs/okio-1.10.0.jar’)

            Thanks Ravi for the tutorial.

  • Rami Sohail

    Awesome tutorial can you post more retrofit series videos..

    There are really important maybe some retrofit with php app with writing and reading and authentication ..

    This will provide complete set of information ..

    Looking forward to next tutorials

    Thank you ravi

  • Han

    thanks ravi for great tutorial, i followed all your code in this article. I’m trying to make recyclerview which show the data from restaurant. The retrofit has succeeded get data from server, in log the data return in number of all registered restaurant. But i got an error, like “no adapter attached skipping layout in activity”. Can you help me ? thanks

  • Slametz Pembuka

    how to create detail view from list view..

  • Aladdin Hamzeh

    Hello, another great tutorial from you :).
    What exactly do I need to make POST call not GET.
    Also if I’m using realm can I convert directly from Json response to realm model ?

  • surya

    Hi Ravi,
    Nice tut…Can you share the tut for getting XML response from http calls using retrofit..

  • |/|@¥@|||€

    retrofit.RetrofitError: Unable to resolve host
    : No address associated with hostname

    • Hitesh Danidhariya

      Check your URl and it should have procol too i.e http://

  • Atish Agrawal

    I think you missed to add “movies_recycler_view” in your activity_main.xml

  • dhiraj kumar

    Thanks for the great tutorial, there is a small update
    In ApiInterface

    Instead of
    @GET(“movie/{id}”)
    Call getMovieDetails(@Path(“id”) int id, @Query(“api_key”) String apiKey);

    It will be

    @GET(“movie/{id}”)
    Call getMovieDetails(@Path(“id”) int id, @Query(“api_key”) String apiKey);

    • Exactly I was wondering , why I wasn’t getting a response even after passing id and api key properly!

    • Nithin Prasad

      Hi Dhiraj,

      Can you please post your onCreate method from the MainActivity.java. Please.

      Thanks,
      Nithin

  • User X

    I got this error: Could not identify launch activity: Default Activity not found
    Error while Launching activity

    Why when I change the MainActivity to the subpackage activity the manifest doesn’t recognize it?

    • User X

      After analyzing your demo, I realized my packages weren’t at the main folder, they were outside so the manifest and layout coulnd’t find the MainActivity. I corrected them and everything went ok! Nice practice.

  • |/|@¥@|||€

    Hello sir, how to handle errors in retrofit?

  • Where is the Recycler view xml? U missed I thnink..

  • Hemant Verma

    how to get all values of a row element on another page

  • kaveesh kanwal

    how to retry retrofit request in 2.x ?

  • vinod

    can we use REST api with JDBC(Mysql) database!!!!!!!!!!!

  • Muhammad Salma Nabila Alibasyi

    can you give me example to make seach filter on bar using retrofit recyclerview?

  • Ziigic

    Thank you Ravi… That’s Awesome. 🙂

  • Tahir Choudhry

    Nice Ravi … it gave awesome concept

  • Nice ! Thank You 😀

  • Eto

    how to store data to sqlite before attach it to recyclerview

    • jermaine maragh

      create a database helper class and when a successful request has been made, you call your database helper class to store the data(List), then add that data to your adapter.add.

  • Thanks a ton for writing tutorials, like always 🙂
    A small place where you need to rectify, please update
    @GET(“movie/{id}”)
    Call getMovieDetails(@Path(“id”) int id, @Query(“api_key”) String apiKey);
    to
    @GET(“movie/{id}”)
    Call getMovieDetails(@Path(“id”) int id, @Query(“api_key”) String apiKey); since it will return a movie object as a response based on id !

    final Call movieCall=apiService.getMovieDetails(id,getResources().getString(R.string.API_KEY));
    movieCall.enqueue(new Callback() {
    @Override
    public void onResponse(Call call, Response response) {
    Movie movies = response.body();
    Log.d(“overview “,”:”+movies.getOverview());
    }

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

    }
    });

    • Thank. I’ll verify once.

    • Hi I’m trying to follow your code here to get my code to run. here is a part of my MainActivity.java

      Call call = apiService.getTopRatedMovies(API_KEY);
      call.enqueue(new Callback() {

      @Override
      public void onResponse(Callcall, Response response) {
      int statusCode = response.code();
      List movies = response.body().getResults();
      recyclerView.setAdapter(new MoviesAdapter(movies, R.layout.list_item_movie, getApplicationContext()));
      }

      @Override
      public void onFailure(Call call, Throwable t) {
      // Log error here since request failed
      Log.e(TAG, t.toString());
      }
      });
      //new stuff
      Call movieCall = apiService.getMovieDetails(id,getResources().getString(R.string.API_KEY));
      movieCall.enqueue(new Callback() {

      @Override
      public void onResponse(Callcall,Response response) {
      Movie movies = response.body();
      Log.d(“overview “,”:”+movies.getOverview());
      }

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

      }
      });

      //end of new stuff

      but the final id and API_KEY above remain in red

      Wondering if I have made some small mistake I just cant see. any help appreciated.

  • visualskyman

    Excellent Tutorials, Great for Newbies like me.
    only one Feedack, do mention adding recycleview in ‘R.layout.activity_main’

  • Renan Bolonha

    Hello, how i do a PUT send an object ?
    Is it right ?

    @PUT(“taskss/{id}”)
    Call updateTask(@Path(“id”) int id, @Body Task task);

  • Eto

    Hi Ravi, where do I can add Logging Interceptor? thanks

  • Hitesh Matnani

    How to add retrofit library with proguardFiles minifyEnabled true in android?

  • Deepti Chaudhari

    Hi Ravi…

    i wanted to know how to call service using retrofit with authentication token. I wanted to add authenticcation token in header of Retrofit… and then call the service… plz guide me on it.

  • PINKesh Darji

    Thanks for such easy tutorial, Can you please let us know how cache a response in retrofit2?
    Use case:
    cache and show response for 1 minute(If internet available)
    cache and show response for 1 week (If internet not available)
    Also how to make use to last updated field in json response to improve effectiveness of cache.

  • murtaza

    where is the movies_layout .

    • I must have forgot to add. Find it in downloaded code.

  • Abhinav Soni

    can you show on click listener method ….and how to call different link with same apiInterface

  • nagendra

    Hi ravi, I would like to display the images along with the text using the “poster-path” value, can u provide any sample example or code snippet or a simple explanation would do.. Thx a ton!! danyavadamulu!! 🙂

  • ALED

    Great Job Ravi,

    But i need your help, could you please provide tutorial how to consume SOAP WebService using Retrofit, especially with Retrofit 2.x with retriveing data and post anything to SOAP WebService , I am very appreciate if you can help me thanks, i was tired to reach out in google page but not found the best solution example tutorial about consume SOAP with Retrofit,

    very thanks, Brad

    • Hi ALED

      Do you really want to support SOAP services? Are the services are third party or of your own?

      • ALED

        Thanks, for your reply brad, no actually i am newbie on android developmnet, i was already create web service using SOAP, i guess i can implement on android, because i less experience with REST, just want to know, this is for learning only, if you have more knowledge to consume SOAP using Retrofit please help me out this issue, thanks.

  • saurabh sarpotdar

    hi ravi…can u tell me wht exctly getTopRatedMovies in statement ‘Call getTopRatedMovies()’ is..? means it is like a method right..? and we can give it any name irrespective of our model class…means I dnt need to have a getTopratedMovies() in my parent class i.e. MoviesResponse..i can give it any name..right..?
    plus I want to pass api_key,api_secret and an id thru json request body…how can i use @Body for that..?along with header of content-type

  • Ashish Singh

    Ravi, My Api response printed in the log but .enqueue method is not invoke . So unable to get the json response. Any idea !! (I’m calling multiple APIs in the Intentservice).

  • praneeth kumar

    I have a Problem while using POST to server using php! please update code with post method also.

  • Miguel Awili

    Hello! I’m having a problem with implenting this in my application. I can’t seem to get the value in the first try, however, when i click it for the second time, it actually works. Can you help?

  • anamika arya

    https://uploads.disquscdn.com/images/e9ed1d64d016fbe28c30425e2730b436a79a52aa261218d3e1a2bd7b9f701fd4.png hi ravi
    how to do parsing if we get the Json Array instead of Json Object as a json responce?

    • sameer khan

      JSONArray jsonarray = new JSONArray(jsonStr);

      for (int i = 0; i < jsonarray.length(); i++) {

      JSONObject jsonobject = jsonarray.getJSONObject(i);

      String name = jsonobject.getString("name");

      String url = jsonobject.getString("url");

      }

      • anamika arya

        Thanks for the reply Sameer

        • sameer khan

          Welcome 🙂

  • Hi Ravi.
    When I run this code I get no gradle errors but it crashes on starting. This is my logcat any ideas what it might be and how to fix it?

    ——— beginning of crash
    E/AndroidRuntime: FATAL EXCEPTION: main
    Process: davidfoale.info.retrofit, PID: 2461
    java.lang.NullPointerException: Attempt to invoke virtual method ‘java.util.List davidfoale.info.retrofit.model.MoviesResponse.getResults()’ on a null object reference
    at davidfoale.info.retrofit.activity.MainActivity$1.onResponse(MainActivity.java:53)
    at retrofit2.ExecutorCallAdapterFactory$ExecutorCallbackCall$1$1.run(ExecutorCallAdapterFactory.java:68)
    at android.os.Handler.handleCallback(Handler.java:739)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at android.os.Looper.loop(Looper.java:148)
    at android.app.ActivityThread.main(ActivityThread.java:5417)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
    I/Process: Sending signal. PID: 2461 SIG: 9
    Application terminated.

    • Vikas Kumar

      Hey I am also getting same error have you found the solution

      • Nithin Prasad

        Hi Vikas,

        Did you get to know any work around on this issue? I am facing the same issue.

        Thanks,
        Nithin

        • Vikas Kumar

          Yes I have found the solution I was not making API call properly.
          Actually in the API interface I was doing @GET(movie/top-rated) instead of @GET(movie/top_rated).

          • Nithin Prasad

            Hi Vikas,

            Thanks for the reply, but my code is all fine in the API interface. I tried downloading and importing the project hosted here and I keep getting the error:

            FATAL EXCEPTION: main
            Process: info.androidhive.retrofit, PID: 4469
            java.lang.NullPointerException: Attempt to invoke virtual method ‘java.util.List info.androidhive.retrofit.model.MoviesResponse.getResults()’ on a null object reference
            at info.androidhive.retrofit.activity.MainActivity$1.onResponse(MainActivity.java:52)
            at retrofit2.ExecutorCallAdapterFactory$ExecutorCallbackCall$1$1.run(ExecutorCallAdapterFactory.java:68)
            at android.os.Handler.handleCallback(Handler.java:746)
            at android.os.Handler.dispatchMessage(Handler.java:95)
            at android.os.Looper.loop(Looper.java:148)
            at android.app.ActivityThread.main(ActivityThread.java:5443)
            at java.lang.reflect.Method.invoke(Native Method)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:728)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)

            Regards,

            Nithin Prasad

          • Vikas Kumar

            Some problem is there u are not getting data from the network only that is why you are getting Null pointer exception

    • Nithin Prasad

      Hi David,

      Did you get to know any work around on this issue? I am facing the same issue.

      Thanks,
      Nithin

      • Valani Bhavesh

        provide code

  • Nizzam

    Is it retrofit as singleton ?

  • Dharmar Gurusamy

    When I run the program, there was no display on the screen except the heading “Retrofit” on the top tool bar.
    In the MainActivity ther is no statement for initializing and setting the adapter.
    recyclreView.setAdapter(adapter); is not there.

  • Dharmar Gurusamy

    I am sorry. It is given at the end

  • agusalay

    how to get data from page larger than 1? 😀

  • hi, Ravi! Thanks for the tutorial, just a small question. Which one would you prefer between the two? Volley or Retrofit?

  • Saathwik Nalige

    i can’t get the api key from your refered website….
    Can i get the api key from someplace else???

  • Yash

    Hi Ravi, I’m done with this part. How do get information of clicked item onto next activity using getMovieDetails() method?

    • Joseph Joey

      Implement recycler itemtouch listener class or implement a clicklistener on your viewholder class. Google and stackoverflow will help out with these concepts.

  • Siranjeevi

    Hi Ravi I need to know how to do Error Handling Preparations…which means if i get 401 response code..means the callback method not fired.. how to handle it.. please let me know

    • HTTP 401 means that the website requires authentication and it was not provided or it failed. You need to authenticate yourself.

  • Prathibha Nandini

    Hello Mr. Tamada (@ravi8x:disqus ) I’ve a Json which includes string, objects, arrays, objects within arrays, arrays within objects. How do I parse such data. The link from ‘themoviedb’ has 1 array which has few values. But my Json has objects within that array.

    • Give me example of your json. You need to create multiple model classes depending on types of nodes it has.

      • Prathibha Nandini

        JSON example:

        Temporary Link: http://paste.ofcode.org/dtpjqLC2rFzTA3RajgFW2N

        {
        “key1″:”value 1”,
        “key2″:”value 2”,
        “key3”:{
        “key4″:”value 4”,
        “key5”:[
        {
        “key6″:”value 1”,
        “key7″:”value 2”
        },
        {
        “key8″:”value 1”,
        “key9″:”value 2”
        }
        ],
        “key10″:”value 1”
        },
        “key11″:”value 2”
        }

        I felt it much difficult with Model classes.

        Using Retrofit, Interface, getClient() etc I’ve retrieved the JSON, assigned it to a Json object and parsed it normally. Like
        String key = jsonObject.getString(“key1”);
        and similarly for array.

        Is it a good approach?

  • Joseph Joey

    Hello Ravi, nice tutorial. I have followed every step of this tutorial and it’s very helpful. Unfortunately, when I run the application, it shows this error E/RecyclerView: No adapter attached; skipping layout and nothing is displayed.
    What could be causing this?

    • Can you give me the code where you attached the adapter to recycler view.

      • Joseph Joey

        I have mailed you the files. Please have a look.

        • Vikas Kumar

          Hey I am also getting the same error Have you found the solution

          • Raju Mandala

            Hi I am also getting the sam error. Did you get this resolved?

    • Nalaka

      I also having the same issue. if you got the solution from ravi, please comment here. Thanks.

  • Parag Kadam

    Hi Ravi,
    Is there a way of pausing and resuming downloads using retrofit? It would be great if you could try to answer this question on stackoverflow –> http://stackoverflow.com/questions/39915855/pause-and-resume-downloads-using-retrofit

  • Prasanna S

    Hello Ravi,
    Great work with the tutorial.
    I just want to know how to request with headers in Retrofit. Could you give me a gist of the same?

    Thanks in advance.

    • Hi Prasanna

      Check the following
      http://stackoverflow.com/questions/18478258/android-retrofit-parameterized-headers

      Here is the code I am using

      public class ApiClient {
      private static Retrofit retrofit = null;
      private static int REQUEST_TIMEOUT = 60;
      private static OkHttpClient okHttpClient;

      public static Retrofit getClient() {

      if (okHttpClient == null)
      initOkHttp();

      if (retrofit == null) {
      retrofit = new Retrofit.Builder()
      .baseUrl(Config.BASE_URL)
      .client(okHttpClient)
      .addConverterFactory(GsonConverterFactory.create())
      .build();
      }
      return retrofit;
      }

      private static void initOkHttp() {
      OkHttpClient.Builder httpClient = new OkHttpClient().newBuilder()
      .connectTimeout(REQUEST_TIMEOUT, TimeUnit.SECONDS)
      .readTimeout(REQUEST_TIMEOUT, TimeUnit.SECONDS)
      .writeTimeout(REQUEST_TIMEOUT, TimeUnit.SECONDS);

      httpClient.addInterceptor(new Interceptor() {
      @Override
      public Response intercept(Interceptor.Chain chain) throws IOException {
      Request original = chain.request();
      Request.Builder requestBuilder = original.newBuilder()
      .addHeader("Authorization", "Bearer " + Config.API_KEY)
      .addHeader("Accept", "application/json");

      Request request = requestBuilder.build();
      return chain.proceed(request);
      }
      });

      okHttpClient = httpClient.build();
      }

      public static void resetApiClient() {
      retrofit = null;
      }
      }

      • Prasanna S

        Thank you so much for the response. I had to dynamically add the headers, so I injected @Header annotation in my ApiInterface.
        Thank you for the help though 🙂

        • Awesome. It would be great if you could provide your code. So that it will be useful to others.

          • Prasanna S

            ApiInterface:-

            @Multipart
            @POST(“getuser”)
            Call getUser(@Header(“Authorization”) String token);

            MainActivity:-

            InterfaceRetrofit apiService = RetroFitApiClient.getClient().create(InterfaceRetrofit.class);
            Call call = apiService.getUser(getToken() /* Your token */ );

            call.enqueue(new Callback() {
            @Override
            public void onResponse(Call call, Response response) {
            // Handle response
            }

            @Override
            public void onFailure(Call call, Throwable t) {
            // Log error here since request failed
            Log.e(TAG, t.toString());
            }
            });

          • Thanks.

  • Andreia Vicente

    Hi Ravi, I’m trying to get a List of the movies genres, I need a new adapter? how can I do that?

  • FreshStart

    Hello Ravi, an obvious question perhaps. Would the above example with Retrofit presumably apply to other similar third party Api’s? For example, library APIs that provide weather or job details? It would be a case of then integrating the API with your own custom code?

  • Muruga Kutti Vel

    @ravi8x:disqus : I need a help to u about POST method can u share the example …. String value send through server..

  • Biniam A.

    Thanks for the fantastic article/tutorial.

    Two points:

    1. You can use http://www.jsonschema2pojo.org/ to generate the POJO file from the JSON.

    2. list_item_movie.java should be list_item_movie.xml

    • swapnil wakchaure

      which type of POJO need to generate GSON or Jackson .

      • Akash Agarwal

        GSON as you are using GSONConverterFactory

  • Mostafa Alsabagh

    this error is showed to me ..can anyone help with the solution .. and the reason ?

    E/RecyclerView: No adapter attached; skipping layout
    E/RecyclerView: No adapter attached; skipping layout
    E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.ms_alsabagh.retrofit_toturial, PID: 25234
    java.lang.NullPointerException: Attempt to invoke virtual method ‘java.util.List com.example.ms_alsabagh.retrofit_toturial.model.MoviesResponse.getResults()’ on a null object reference
    at com.example.ms_alsabagh.retrofit_toturial.activity.MainActivity$1.onResponse(MainActivity.java:51)
    at retrofit2.ExecutorCallAdapterFactory$ExecutorCallbackCall$1$1.run(ExecutorCallAdapterFactory.java:68)
    at android.os.Handler.handleCallback(Handler.java:739)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at android.os.Looper.loop(Looper.java:168)
    at android.app.ActivityThread.main(ActivityThread.java:5845)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:797)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:687)

  • prasad Vdv

    Here my issue

    I’m trying to make XML Response, but there is an exception.

    Exception in onFailure: org.simpleframework.xml.core.ElementException: Element ‘Date’ does not have a match in class

    Client

    public static Retrofit getXMLClient() {

    if (retrofitXML == null) {
    retrofitXML = new Retrofit.Builder()
    .baseUrl(BASE_URL)
    .client(okHttpClient)
    .addConverterFactory(SimpleXmlConverterFactory.create())
    .build();
    }
    return retrofitXML;
    }
    Interface

    @GET(“odds-” + oddsAccessMode + “1”+”?”)
    Call getOddsData(@Query(“api_key”) String api_key);
    API call

    ApiInterfaceSR apiService =
    ApiClientSR.getXMLClient().create(ApiInterfaceSR.class);
    Call call = apiService.getOddsData(API_KEY);
    call.enqueue(new Callback() {

    @Override
    public void onResponse(Call call, Response response) {
    if (response.body() != null && response.code() == 200) {
    try {
    String s = response.body().toString();
    Log.d(TAG, “onResponse: “+s);
    } catch (Exception e) {
    Log.e(“JSON exception”, e.getMessage());
    }
    }
    }

    @Override
    public void onFailure(Call call, Throwable t) {
    Log.e(“api exception”, t.getMessage());
    }
    });

    http://stackoverflow.com/questions/42716563/xml-parsing-using-retrofit

  • Umesh Nepali

    My Json Response like below.
    {
    “success”: “1”,
    “data”: [
    {
    “address”: “Hufffdtel de Ville, 75004 Paris, France”,
    “email”: “umesh.nepali@indianic.com”,
    “username”: “umeshfinal”,
    “phone”: “9033329824”,
    “status”: 0,
    “fld_help_id”: 97979,
    “recieveremail”: “brinda@gmail.com”,
    “image”: “http://services.defensealertdevice.com/admin/uploads/user_image/user_image_2094.png”,
    “latitude”: “48.8564817”,
    “longitude”: “2.3524133”,
    “datetime”: “2017-03-03 10:50:03.0”,
    “alertType”: 0
    },
    {
    “address”: “Skufffdufffdabraut, Dalvufffdk, Iceland”,
    “email”: “brinda@gmail.com”,
    “username”: “chil”,
    “phone”: “1234567890”,
    “status”: 0,
    “fld_help_id”: 97980,
    “recieveremail”: “brinda@gmail.com”,
    “image”: “http://services.defensealertdevice.com/admin/uploads/user_image/user_image_2843.png”,
    “latitude”: “65.9667”,
    “longitude”: “-18.5333”,
    “datetime”: “2017-03-03 10:34:51.0”,
    “alertType”: 3
    },
    {
    “address”: “Skufffdufffdabraut, Dalvufffdk, Iceland”,
    “email”: “brinda@gmail.com”,
    “username”: “chil”,
    “phone”: “1234567890”,
    “status”: 0,
    “fld_help_id”: 97981,
    “recieveremail”: “brinda@gmail.com”,
    “image”: “http://services.defensealertdevice.com/admin/uploads/user_image/user_image_2843.png”,
    “latitude”: “65.9667”,
    “longitude”: “-18.5333”,
    “datetime”: “2017-03-03 10:34:51.0”,
    “alertType”: 4
    },

    {
    “address”: “ISKCON Cross Rd, Ramdev Nagar, Ahmedabad, Gujarat 380015, India”,
    “email”: “brinda@gmail.com”,
    “username”: “brinda”,
    “phone”: “1234567890”,
    “status”: 0,
    “fld_help_id”: 97702,
    “recieveremail”: “brinda@gmail.com”,
    “image”: “http://services.defensealertdevice.com/admin/uploads/user_image/user_image_2843.png”,
    “latitude”: “23.0252983”,
    “longitude”: “72.5075467”,
    “datetime”: “2017-03-02 15:32:49.0”,
    “alertType”: 3
    },
    {
    “address”: “ISKCON Cross Rd, Ramdev Nagar, Ahmedabad, Gujarat 380015, India”,
    “email”: “brinda@gmail.com”,
    “username”: “brinda”,
    “phone”: “1234567890”,
    “status”: 0,
    “fld_help_id”: 97700,
    “recieveremail”: “brinda@gmail.com”,
    “image”: “http://services.defensealertdevice.com/admin/uploads/user_image/user_image_2843.png”,
    “latitude”: “23.0252983”,
    “longitude”: “72.5075467”,
    “datetime”: “2017-03-02 15:31:20.0”,
    “alertType”: 3
    },

    {
    “address”: “ISKCON Cross Rd, Ramdev Nagar, Ahmedabad, Gujarat 380015, India”,
    “email”: “umesh.nepali@indianic.com”,
    “username”: “umeshfinal”,
    “phone”: “9033329824”,
    “status”: 0,
    “fld_help_id”: 97680,
    “recieveremail”: “brinda@gmail.com”,
    “image”: “http://services.defensealertdevice.com/admin/uploads/user_image/user_image_2094.png”,
    “latitude”: “23.02571”,
    “longitude”: “72.5077717”,
    “datetime”: “2017-03-02 14:25:38.0”,
    “alertType”: 0
    },

    {
    “address”: “Flensborggade 40, 1669 Kufffdbenhavn V, Denmark”,
    “email”: “brinda@gmail.com”,
    “username”: “brinda”,
    “phone”: “1234567890”,
    “status”: 0,
    “fld_help_id”: 97708,
    “recieveremail”: “brinda@gmail.com”,
    “image”: “http://services.defensealertdevice.com/admin/uploads/user_image/user_image_2843.png”,
    “latitude”: “55.6655517”,
    “longitude”: “12.5474717”,
    “datetime”: “2017-03-02 11:06:33.0”,
    “alertType”: 3
    }
    ],
    “message”: “”
    }

    Can you just tell me model class and response class for above response?.
    I got onResponse with status code=200 but i would not able to get array of data from the data tag.
    thanks in advance.

  • Ibrahim Samad

    Hi Ravi, If I want to make a GET request but then update the database depending on the response I get. In this case should I use PUT because I need to update or I should stick with the get and pass the parameters along.

  • RAja Jakkampudi

    ApiInterface apiInterface= ApiClient.getClient().create(ApiInterface.class);

    Am getting error in above line saying create()

    https://uploads.disquscdn.com/images/4e4a01d05d1e5ba6f1da8c643bf51756222a5ec2deef521f7ba4ba8f6245c2c3.png

  • Very nice tutorial.

  • Abl Bekdoullaev

    Hi Ravi, thank you for your very detailed tutorials! How can i get 20 more movies from the next page?

    • You need to use paging if there are providing. Consider getting the next page onRecyclerView scroll to bottom.

      • Abl Bekdoullaev

        Thank you, Sir, for replying. There is one problem: i don’t have field ‘page’ or something similar in my API.
        I have certain ideas how to expand my RecyclerView for new results. But first, i need to get those new results. By default, when i make a call, it returns me only 10 objects inside Json. I can’t change initial number of received objects either. I will attach sctructure of my JSON.
        Please give me an advice

        https://uploads.disquscdn.com/images/8ef3b938f7d3287a5fd3de5a2af6b3af4a8d19b046e7b4791f1f11a96547a480.png

        • Who is writing the services? Is the data is hosted on your server?

          • Abl Bekdoullaev

            no, i’m using opensource API “newsapi.org”, which requests json from ~80 different sources of news. I assume, it’s impossible to do without “id” or “page” key?

  • Andika Afif

    sir, what is the difference between a Movie.class with the MovieResponses.class

    • Movie denotes single movie object. MovieResponse.class contains list of movies along with other data like paging etc.,

  • sayar samanta

    @ravi8x:disqus Sir in point no 14 it should be list_item_movie.xml not .java

  • Ankit Palli

    Ravi Tamada I really love your tutorials simplicity and always follow you in my life…
    This tutorial is really simple and great detailed…
    Please keep up the work…
    We are your fans.

    http://spartacoder.blogspot.in/2017/04/how-to-use-retrofit-to-send-and-receive.html

  • QuentaMelkor

    Is there any tutorials of yours, where you have showed how to make this commenting like option and like and dislike option?

    • I don’t have any right now.

      • QuentaMelkor

        Can you make one please, whatever logic I am applying, it has flaws? 🙇

  • Alpit Anand

    ApiInterface apiService =
    ApiClient.getClient().create(ApiInterface.class);

    I am not able to follow this line ?

  • hussain ahmad

    Getting this error again and again , i don’t know why this error is occouring again and again
    com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 1 path $
    05-19 16:05:26.109 17374-17374/com.hussain.progosteach.lithoproductdetail_elabelz W/System.err: at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:224)
    05-19 16:05:26.109 17374-17374/com.hussain.progosteach.lithoproductdetail_elabelz W/System.err: at retrofit2.converter.gson.GsonResponseBodyConverter.convert(GsonResponseBodyConverter.java:37)
    05-19 16:05:26.109 17374-17374/com.hussain.progosteach.lithoproductdetail_elabelz W/System.err: at retrofit2.converter.gson.GsonResponseBodyConverter.convert(GsonResponseBodyConverter.java:25)
    05-19 16:05:26.109 17374-17374/com.hussain.progosteach.lithoproductdetail_elabelz W/System.err: at retrofit2.ServiceMethod.toResponse(ServiceMethod.java:118)
    05-19 16:05:26.109 17374-17374/com.hussain.progosteach.lithoproductdetail_elabelz W/System.err: at retrofit2.OkHttpCall.parseResponse(OkHttpCall.java:212)
    05-19 16:05:26.109 17374-17374/com.hussain.progosteach.lithoproductdetail_elabelz W/System.err: at retrofit2.OkHttpCall$1.onResponse(OkHttpCall.java:106)
    05-19 16:05:26.109 17374-17374/com.hussain.progosteach.lithoproductdetail_elabelz W/System.err: at okhttp3.RealCall$AsyncCall.execute(RealCall.java:135)
    05-19 16:05:26.109 17374-17374/com.hussain.progosteach.lithoproductdetail_elabelz W/System.err: at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
    05-19 16:05:26.109 17374-17374/com.hussain.progosteach.lithoproductdetail_elabelz W/System.err: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
    05-19 16:05:26.109 17374-17374/com.hussain.progosteach.lithoproductdetail_elabelz W/System.err: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
    05-19 16:05:26.109 17374-17374/com.hussain.progosteach.lithoproductdetail_elabelz W/System.err: at java.lang.Thread.run(Thread.java:818)
    05-19 16:05:26.109 17374-17374/com.hussain.progosteach.lithoproductdetail_elabelz W/System.err: Caused by: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 1 path $
    05-19 16:05:26.109 17374-17374/com.hussain.progosteach.lithoproductdetail_elabelz W/System.err: at com.google.gson.stream.JsonReader.beginObject(JsonReader.java:385)
    05-19 16:05:26.109 17374-17374/com.hussain.progosteach.lithoproductdetail_elabelz W/System.err: at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:213)
    05-19 16:05:26.109 17374-17374/com.hussain.progosteach.lithoproductdetail_elabelz W/System.err: … 10 more

  • Pradip Vora

    My Responce is :

    {
    “animal_wall”: [
    {
    “error_code”: “4”,
    “error_msg”: “No Any Error Found”,
    “user”: “Old User”,
    “version_status”: {
    “version_code”: 1,
    “version_msg”: “latest version available. Download it”,
    }
    }
    ]
    }

    My Proble is that How can print “version_status” jsonObject And in this block…
    Responce data fetch..but i don’t know idea how can print it.

    how can print nested JsonObject or JsonArray print in adapter class.
    Please help me for solution my problem Sir…..!!

  • Razi

    Hi, Ravi Tamada I really love your tutorials , now i getting this error can u help me please. thanks

    E/RecyclerView: No adapter attached; skipping layout
    W/art: Before Android 4.1, method int android.support.v7.widget.ListViewCompat.lookForSelectablePosition(int, boolean) would have incorrectly overridden the package-private method in android.widget.ListView
    E/RecyclerView: No adapter attached; skipping layout
    D/AndroidRuntime: Shutting down VM
    E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.apple.practise, PID: 5244
    java.lang.NullPointerException: Attempt to invoke virtual method ‘java.util.List com.example.apple.practise.model.MovieResponseDetail.getResults()’ on a null object reference
    at com.example.apple.practise.MainActivity$1.onResponse(MainActivity.java:53)
    at retrofit2.ExecutorCallAdapterFactory$ExecutorCallbackCall$1$1.run(ExecutorCallAdapterFactory.java:68)
    at android.os.Handler.handleCallback(Handler.java:739)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at android.os.Looper.loop(Looper.java:148)
    at android.app.ActivityThread.main(ActivityThread.java:5417)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

    • Hissam Yousaf

      you need to attach your Adapter to the Recyclerview . add this code in onCreate of main activity before making network call

      recyclerView.setAdapter(new MoviesAdapter(movies, R.layout.list_item_movie, getApplicationContext()));

      In the above code it will work fine and will not show “No adapter attached; skipping layout” error only if your network call was successful and you are getting some response. If no internet is available or you get onFailure(), you’ll see this error because this setAdapter is in onResponse. So you should setAdapter before making the networkcall in onCreate and you’ll be fine.

  • Manisha Khatke

    which is best volley or retrofit?

    • russel

      retrofit

      • Adrian Banda

        why retrofit instead of volley?

    • Ankit

      for me Retrofit is the good one

  • Xantosh Pristine Lamsal

    For those who are getting null pointer exception error at mainActivity.java, Change the code at creating recyclerview object to this:

    final RecyclerView recyclerView = (RecyclerView) findViewById(R.id.movies_recycler_view);
    final LinearLayoutManager layoutManager = new LinearLayoutManager(this);
    layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
    recyclerView.setLayoutManager(layoutManager);

  • sc_calcutta

    can not understand the interface’s work. Is it making the urls to fetch or upload data to service . Explain a bit more how to create those

  • Akki

    My api is return only 100 record how to i get after 100 Record or next 100 record please help..

    • Anshul Singhla

      Use pagination technique

  • Osama Inam

    Hi I am using retrofit for my app and Im using this URL= “https://dev-us-02.oction.co/api/v1/auctions”;
    It works fine in Web Browsers and PostMan. But When I add it to my app using retrofit it gives an error
    IOException:Connection closed by peer.
    Can you help ? Its only coming in android. Works in iOS

  • Anshul Singhla

    Simple and nice tutorial to get started with Retrofit library. I have one question, why did you create a constructor for Movie class and not for MovieResponse class? Do we really need constructor in any of them?
    Sorry if it is dumb question.
    Thanks

    • An empty constructor will be created automatically even though you forget also. There is no harm in not defining one, but you need empty constructor if you want to initialize any variable or anything.

  • ah lee

    it is really nice tutorial sir~may I ask you a question?
    when i compile the coding using android studio, I can’t resolve “R.id.movies_recycler_view” ~can you help me find out where is the problem? thank you sir
    sorry for my broken english

    • Ankit Bhalodiya

      you should import the r.java file when you do this
      what you have to do is just type “import (your application package).R” that’s it…
      thanks

      • ah lee

        i already done so but the problem doesn’t solved~any other ways?

  • Ankit Bhalodiya

    I used the same code but i get an error
    com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was NUMBER at line 1 column 31 path $.total_results

    i don’t know how to handle it….!

  • Omar Beshary

    You are the best , thank you .

  • Venkat Raman

    Hi Ravi,
    Nice Tutorial!!!

    I saw the retrofit request is placed on Main UI thread. But the best practice would be going with async task for placing request.
    Does the retrofit takes that burden from Android?

  • sahaya alex

    when call APIInterface it sayin no such instance field how to fix it?? please help

  • Eduardo Carvalho

    Hi, don’t have references to id=movies_recycler_view in the list_item_movie… How to fix it?? thaks

    • Raj Kumar

      To fix this, you need to create RecyclerView in your activity_main.xml with the id ‘movies_recycler_view’.

  • Muhibb

    Mr. Ravi, This is great tutorial I have seen. I have searched a lot of tutorials for retrofit but this very helpful.
    I have a single question please tell how to get API KEY ?

    • What do you meant by ‘get API KEY’. Please explain your query.

  • didik

    Mr. Ravi this great tutorial, when i want to get data from cloud like thingspeank or ubidot maybe. what the method same like this? thanks you

  • hameedullah

    bro iam getting error saying Attempt to invoke virtual method ‘java.util.List com.example.admin.retrofitdemo.model.MovieResponse.getResults()’ on a null object reference

  • hameedullah

    please reply as early as possible

  • hameedullah

    iam getting error

  • hameedullah

    i solved it
    it was Call getTopRatedMovies(@Query(“api_key”) String apiKey);
    and i have written Call getTopRatedMovies(@Query(“api key”) String apiKey);
    if you observe the mistake it is underscore between api,key well i gave space so i was facing the error

  • DANIEL WARUI NDUNG’U

    do you mind doing an example with posting a JSON Objest where you get back a List

  • Surendra Bharathi

    Thanks for the tutorial..What to do if we want to display genre_ids..do we need to write separate modal?

  • Osman EKİZ

    ı want to get information mysql database? Not json.
    How can ı?

  • Raj Kumar

    For all who are getting this error
    “Cannot resolve R.id.movies_recycler_view”,

    you need to create a RecyclerView in your activity_main.xml with the id ‘movies_recycler_view’.

    And Thanks to Ravi for this excellent tutorial.

  • shashi patil

    mail me ur id i ll send u my adapter class

    • Sheetal

      its done now thank u 🙂

      • shashi patil

        Ok

  • Vishal Bhandare

    Thank you for the nice article. Will you please share some info. about adding header for GET request?

  • Sheetal

    hello Thanks for rply its wotk fine now.. i am working on dummy project fetch json like gmail on edit text filed, there is an issue i fecth the json , also genrate autocomplete text field but json is not displyaing in edittext click ant help???