Hey guys, so here is a Retrofit Android Example for you. In this post, we will learn to fetch JSON data from a given URL.
Table of Contents
What is Retrofit?
You might be knowing that in almost every Android project we need to work with APIs, which is nothing but an HTTP call to a particular URL. And we have already done this thing in some previous posts, an example you can see from the below-given link.
Android JSON Parsing using AsyncTaks
If you have been through the above post, then you know how much code we need to write for the network operation. And at the same time, we need to take care of a hell lot of things, like memory, cache, etc. So to make the life easier we have some libraries that can simplify our task. And Retrofit is one of the most popular used libraries for this job.
The API
The URL that gives us some data or to some task upon sending an HTTP request is called an API. And for this example, I already have an API, so you do not need to create the API. Below is our API URL.
https://simplifiedcoding.net/demos/marvel/
If you go to the above URL, you will get a response as shown below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
[ { "name": "Captain America", "realname": "Steve Rogers", "team": "Avengers", "firstappearance": "1941", "createdby": "Joe Simon", "publisher": "Marvel Comics", "imageurl": "https://www.simplifiedcoding.net/demos/marvel/captainamerica.jpg", "bio": "\r\n\t\tSteven Rogers was born in the Lower East Side of Manhattan, New York City, in 1925 to poor Irish immigrants, Sarah and Joseph Rogers.[54] Joseph died when Steve was a child, and Sarah died of pneumonia while Steve was a teen. By early 1940, before America's entry into World War II, Rogers is a tall, scrawny fine arts student specializing in illustration and a comic book writer and artist.\r\n\t\t" }, . . . |
I hope you know about the JSON. So the response we are getting from the above URL is a JSON Array []. If you want to know how to make an API, you can see a detailed post about it from the link given below.
Build REST API using Laravel Lumen for your Application
Now our task is to fetch and parse the above JSON data in our Android Application using the Retrofit Library. So let’s begin.
Retrofit Android Example
Creating a new Project
- Lets first create a new Android Studio Project. I have created a project named RetrofitExample.
- Once the project is created we need to add the following two libraries to our project.
- Retrofit -> For the network calls
- Gson -> For easy parsing of JSON data
Adding Retrofit and Gson
- Adding libraries are very easy. You just need to add the following two lines inside the dependencies block of your app level build.gradle file.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
dependencies { implementation fileTree(dir: "libs", include: ["*.jar"]) implementation 'androidx.appcompat:appcompat:1.2.0' implementation 'androidx.constraintlayout:constraintlayout:2.0.1' testImplementation 'junit:junit:4.12' androidTestImplementation 'androidx.test.ext:junit:1.1.2' androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0' //these two lines are added implementation 'com.squareup.retrofit2:retrofit:2.7.2' implementation 'com.squareup.retrofit2:converter-gson:2.7.2' } |
- You also need to add Java8 compileOptions . Do it inside android block.
1 2 3 4 5 6 |
compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } |
- Now just sync your project and you are done.
Creating API Interface
- To make an API call using retrofit we need a java interface where we define all the URLs with the http request type and parameters. In this example we need to perform an http GET with no extra parameters.
- So lets create a java interface inside and name it Api.java (You can name it anything you want).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
public interface Api { String BASE_URL = "https://simplifiedcoding.net/demos/"; /** * The return type is important here * The class structure that you've defined in Call<T> * should exactly match with your json response * If you are not using another api, and using the same as mine * then no need to worry, but if you have your own API, make sure * you change the return type appropriately **/ @GET("marvel") Call<List<Hero>> getHeroes(); } |
- As you can see we have a very simple interface above. Inside the interface first we have a BASE_URL. It contains the ROOT URL of our API. For any project we make an API like myproject/api/v1/apiname. Retrofit divides it in two parts the first part is the base URL and then the api name. So in our example marvel is the api name and before it we have the BASE URL.Â
- After the base URL we have an annotation @GET(“marvel”). It means that we are defining an http GET request. And the String passed inside the get is the api name. So for this GET it will make the complete URL joining the BASE_URL and the api name.
- Then we have a method named getHeroes() whose return type is Call. And the type of the Call is a List<>. And type of the List is Hero. It may sounds confusing but it is not. Actually we need to structure the api call according the the response. So our URL is giving us an json array and that is nothing but a list of heroes. So we defined the Call type as a List and the List type as Hero. Now we need to define the Hero class.
The Model Class
- Lets create a class named Hero. It will be a simple java class with a constructor and getters. And inside this class we will define all the attributes of our response.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
public class Hero { @SerializedName("name") private String name; private String realname; private String team; private String firstappearance; private String createdby; private String publisher; private String imageurl; private String bio; public Hero(String name, String realname, String team, String firstappearance, String createdby, String publisher, String imageurl, String bio) { this.name = name; this.realname = realname; this.team = team; this.firstappearance = firstappearance; this.createdby = createdby; this.publisher = publisher; this.imageurl = imageurl; this.bio = bio; } public String getName() { return name; } public String getRealname() { return realname; } public String getTeam() { return team; } public String getFirstappearance() { return firstappearance; } public String getCreatedby() { return createdby; } public String getPublisher() { return publisher; } public String getImageurl() { return imageurl; } public String getBio() { return bio; } } |
- Make sure your variable names matches with the JSON attributes. As we have the following JSON objects in our response.
1 2 3 4 5 6 7 8 9 10 11 12 |
{ "name": "Captain America", "realname": "Steve Rogers", "team": "Avengers", "firstappearance": "1941", "createdby": "Joe Simon", "publisher": "Marvel Comics", . . . |
- So for getting this name we have to name our String as name (case sensitive) in the model class. Now if you want to make different names then you can define your model class as below.
1 2 3 4 5 6 |
public class Hero { @SerializedName("name") private String name; |
- So if you put the annotation @SerializedName(“attribute name”) with the json attribute name just above every variable you are defining, you can name your variables anything but you have to put the correct attribute name inside SerializedName(“name”).
Creating Singleton Retrofit Client
If your application uses frequent network calls, then you must create a Singleton Instance of Retrofit. Because creating Retrofit instance every-time when you need to perform a network request is not a good idea.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
public class RetrofitClient { private static RetrofitClient instance = null; private Api myApi; private RetrofitClient() { Retrofit retrofit = new Retrofit.Builder().baseUrl(Api.BASE_URL) .addConverterFactory(GsonConverterFactory.create()) .build(); myApi = retrofit.create(Api.class); } public static synchronized RetrofitClient getInstance() { if (instance == null) { instance = new RetrofitClient(); } return instance; } public Api getMyApi() { return myApi; } } |
- Now to get our API instance we can simply call RetrofitClient.getInstance().getMyApi()Â and then we can call the function getHeroes()Â to make a request to our API.
Making the API Call
- Now the final step is performing the API call. It is also very easy.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
//Creating a call instance using our RetrofitClient //here basically we are calling the method getHeroes() that we created inside //our API Interface Call<List<Hero>> call = RetrofitClient.getInstance().getMyApi().getHeroes(); //to perform the API call we need to call the method enqueue() //We need to pass a Callback with enqueue method //And Inside the callback functions we will handle success or failure of //the result that we got after the API call call.enqueue(new Callback<List<Hero>>() { @Override public void onResponse(Call<List<Hero>> call, Response<List<Hero>> response) { //In this point we got our hero list //thats damn easy right ;) List<Hero> heroList = response.body(); //now we can do whatever we want with this list } @Override public void onFailure(Call<List<Hero>> call, Throwable t) { //handle error or failure cases here Toast.makeText(getApplicationContext(), t.getMessage(), Toast.LENGTH_SHORT).show(); } }); |
- Now let’s do it in our project.
Displaying the Heroes in a ListView
Creating Interface
- Come inside activity_main.xml of your project and create a ListView.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="net.simplifiedlearning.retrofitexample.MainActivity"> <ListView android:id="@+id/listViewHeroes" android:layout_width="match_parent" android:layout_height="match_parent" /> </RelativeLayout> |
Fetching the JSON Data
- Now inside MainActivity.java write the following code.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
public class MainActivity extends AppCompatActivity { ListView listView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); listView = findViewById(R.id.listViewHeroes); //calling the method to display the heroes getHeroes(); } private void getHeroes() { Call<List<Hero>> call = RetrofitClient.getInstance().getMyApi().getHeroes(); call.enqueue(new Callback<List<Hero>>() { @Override public void onResponse(Call<List<Hero>> call, Response<List<Hero>> response) { List<Hero> heroList = response.body(); //Creating an String array for the ListView String[] heroes = new String[heroList.size()]; //looping through all the heroes and inserting the names inside the string array for (int i = 0; i < heroList.size(); i++) { heroes[i] = heroList.get(i).getName(); } //displaying the string array into listview listView.setAdapter(new ArrayAdapter<String>(getApplicationContext(), android.R.layout.simple_list_item_1, heroes)); } @Override public void onFailure(Call<List<Hero>> call, Throwable t) { Toast.makeText(getApplicationContext(), t.getMessage(), Toast.LENGTH_SHORT).show(); } }); } } |
Adding Internet Permission
- As we are performing a network operation, internet permission is needed. So inside your AndroidManifest.xml define the internet permission.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="net.simplifiedlearning.retrofitexample"> <!-- the internet permission --> <uses-permission android:name="android.permission.INTERNET" /> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest> |
- Thats it now you can play your application.
- Bingo! it is working absolutely fine.
Displaying the Heroes in a RecyclerView
- Here I showed only the hero names in a simple ListView, but you can use all the attributes to display. If you are confused how to do this? Here is one more tutorial doing the same with the volley. So once you got the List of heroes in your app, you can implement the process shown here.
Expandable RecyclerView Android – RecyclerView with Expandable Items
- I am using the same api in the link given above so you have to exactly the same thing to display the data in a RecyclerView.
Retrofit Android Example Source Code
- If you are still confused you can get my source code from the link given here.
So that’s all for this Retrofit Android Example friends. Hope you liked it. So if you think it helped you then you, please help us by SHARING this post. Thank You 🙂