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!

Subscribe
Notify of
guest
330 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
varuki
varuki
4 years ago

Thanks for the tutorial

Akriti Chaturvedi
4 years ago

This one is for Retrofit 2.0 ?

Htoo Aung Hlaing
Htoo Aung Hlaing
4 years ago

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

Hossein
Hossein
4 years ago

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

Rakhi Dhavale
4 years ago

Awesome , will execute and Let you know !!

Siranjeevi
Siranjeevi
4 years ago
Reply to  Rakhi Dhavale

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

Rakhi Dhavale
4 years ago
Reply to  Siranjeevi

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
shashi patil
4 years ago
Reply to  Rakhi Dhavale

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

Jay Poojara
4 years ago

woocommerce & wordpress native android app tutorial Please.

Htoo Aung Hlaing
Htoo Aung Hlaing
4 years ago

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

Ravi Tamada
4 years ago

Thnx. I’ll modify it.

Htoo Aung Hlaing
Htoo Aung Hlaing
4 years ago

Thanks Ravi, for your awesome tutorial .

Jojo
Jojo
4 years ago

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.

Cece Syamsul Hadi
Cece Syamsul Hadi
4 years ago
Reply to  Ravi Tamada

Hi Ravi.. Im Sorry,I dont know how to ask for and where..I just need Help.
How to create code when the application has close without Click Button STOP
but music still running,and the icon app appears in bar mobile..
Please Help Me..
cecesyamsul@gmail.com

Mezooo
Mezooo
4 years ago
Reply to  Jojo

RetroFit of course For Restful Api

Volley vs Retrofithttp://i.imgur.com/tIdZkl3.png

Barka Tatama
4 years ago

Thanks

Sandeep Bhambad
Sandeep Bhambad
4 years ago

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

Nam
Nam
4 years ago

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!

Sandeep Bhambad
Sandeep Bhambad
4 years ago
Reply to  Nam
truth
truth
4 years ago

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
Mezooo
4 years ago

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.

Ravi Tamada
4 years ago
Reply to  Mezooo

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

tohin
tohin
4 years ago

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

Bob
Bob
4 years ago

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.

Ravi Tamada
4 years ago
Reply to  Bob

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
tohin
4 years ago

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
tohin
4 years ago

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
Rishabh
4 years ago

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
VARUN BEHL
4 years ago

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

Arslanali
Arslanali
4 years ago

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
Htoo Aung Hlaing
4 years ago

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?

Ravi Tamada
4 years ago

I haven’t tried file upload yet. Pls check this
https://github.com/pratikbutani/RetrofitImageUpload

Pratik Butani
4 years ago
Reply to  Ravi Tamada

Thank you :disqus for Sharing 🙂

Bagus Aji
Bagus Aji
4 years ago

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

Where’s the id movies_recycler_view?

Đỗ Gia Long
Đỗ Gia Long
4 years ago
Reply to  Bagus Aji

in activity_main.xml

Lucian Iacob
Lucian Iacob
4 years ago
Reply to  Bagus Aji

You have to declare an recycler view inside activity_main.xml

Nikhil Katekhaye
Nikhil Katekhaye
4 years ago

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

vxcvxv
vxcvxv
4 years ago

Its Great

Eunan
Eunan
4 years ago

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
chemechaos
4 years ago

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
venkat1017
4 years ago

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

Chandrahasan
Chandrahasan
4 years ago

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

Rivu
4 years ago

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
Nimzy Kevin Maina
4 years ago

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

Ravi Tamada
4 years ago

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
Dexter
4 years ago

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
SelvaGanesh
4 years ago

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

nitish patel
nitish patel
4 years ago

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.

Ravi Tamada
4 years ago
Reply to  nitish patel

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
nitish patel
4 years ago
Reply to  Ravi Tamada

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?

Ravi Tamada
4 years ago
Reply to  nitish patel

Can you give me the exception?

nitish patel
nitish patel
4 years ago
Reply to  Ravi Tamada

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
4 years ago
Reply to  Ravi Tamada

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
jagdish Gupta
4 years ago
Reply to  nitish patel

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
Rami Sohail
4 years ago

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
Han
4 years ago

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
Slametz Pembuka
4 years ago

how to create detail view from list view..

Aladdin Hamzeh
Aladdin Hamzeh
4 years ago

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
surya
4 years ago

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

|/|@¥@|||€
|/|@¥@|||€
4 years ago

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

Hitesh Danidhariya
Hitesh Danidhariya
4 years ago
Reply to  |/|@¥@|||€

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

Atish Agrawal
Atish Agrawal
4 years ago

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

dhiraj kumar
dhiraj kumar
4 years ago

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);

Rakhi Dhavale
4 years ago
Reply to  dhiraj kumar

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

Nithin Prasad
Nithin Prasad
3 years ago
Reply to  dhiraj kumar

Hi Dhiraj,

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

Thanks,
Nithin

User X
User X
4 years ago

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
User X
4 years ago
Reply to  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.

|/|@¥@|||€
|/|@¥@|||€
4 years ago

Hello sir, how to handle errors in retrofit?

Vyshnav Ramesh
4 years ago

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

Hemant Verma
Hemant Verma
4 years ago

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

Vyshnav Ramesh
4 years ago
Reply to  Hemant Verma

pass with intent

kaveesh kanwal
kaveesh kanwal
4 years ago

how to retry retrofit request in 2.x ?

vinod
vinod
4 years ago

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

Ravi Tamada
4 years ago
Reply to  vinod

YES

Muhammad Salma Nabila Alibasyi
Muhammad Salma Nabila Alibasyi
4 years ago

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

Ziigic
Ziigic
4 years ago

Thank you Ravi… That’s Awesome. 🙂

Tahir Choudhry
Tahir Choudhry
4 years ago

Nice Ravi … it gave awesome concept

330
0
Would love your thoughts, please comment.x
()
x