Retrofit API for Android
Retrofit is a type-safe REST client for Android built by Square. Retrofit makes it easy to connect to a REST web service by translating the API into Java interfaces.Using this tool we can make all network stuff much more easier. In this tutorial, I’ll show you how to use one of the most popular and often recommended HTTP libraries available for Android using Post request method.
Step 1: Creating a New Project in Android Studio
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 following dependencies.
1 2 3 |
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. Add Internet Permission in AndroidManifest.xml file.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.vrinfosystem.retrofitdemo"> <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=".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 three sub packages named activity,model and rest in main package.Now,Move MainActivity under activity package.
Step2: Generating Models
We would like to make a POSTrequest (create a new resource) on the API. But before we execute this request, we need to know the JSON response we should expect when it is executed successfully so that Retrofit can parse the JSON response and deserialize it to Java objects.
According to APi,if we will send following data in POST request:
1 2 3 |
{ email:'vrinfosystem@gmail.com' } |
we will get following Response:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
{ "msg": { "company_name": "VR Infosystem", "Company_country": "India", "company_state": "Gujarat", "company_city": "Ahmedabad", "company_skills": [ "android development", "iphone development", "wordpress development", "php \/ codeIgniter", "SEO", "Graphics Designing" ] }, "success": true } |
1.Create a ApiResponse.java under model package .
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 |
package com.vrinfosystem.retrofitdemo.model; import com.google.gson.annotations.Expose; import com.google.gson.annotations.SerializedName; public class ApiResponse { @SerializedName("msg") @Expose private Message msg; @SerializedName("success") @Expose private Boolean success; public Message getMsg() { return msg; } public void setMsg(Message msg) { this.msg = msg; } public Boolean getSuccess() { return success; } public void setSuccess(Boolean success) { this.success = success; } } |
2.create a Message.java class under model package .
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 59 60 61 62 63 64 |
package com.vrinfosystem.retrofitdemo.model; import com.google.gson.annotations.Expose; import com.google.gson.annotations.SerializedName; import java.util.List; public class Message { @SerializedName("company_name") @Expose private String companyName; @SerializedName("Company_country") @Expose private String companyCountry; @SerializedName("company_state") @Expose private String companyState; @SerializedName("company_city") @Expose private String companyCity; @SerializedName("company_skills") @Expose private List<String> companySkills = null; public String getCompanyName() { return companyName; } public void setCompanyName(String companyName) { this.companyName = companyName; } public String getCompanyCountry() { return companyCountry; } public void setCompanyCountry(String companyCountry) { this.companyCountry = companyCountry; } public String getCompanyState() { return companyState; } public void setCompanyState(String companyState) { this.companyState = companyState; } public String getCompanyCity() { return companyCity; } public void setCompanyCity(String companyCity) { this.companyCity = companyCity; } public List<String> getCompanySkills() { return companySkills; } public void setCompanySkills(List<String> companySkills) { this.companySkills = companySkills; } } |
3.Creating a Retrofit Instance
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 RetrofitClient.java under rest package.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
package com.vrinfosystem.retrofitdemo.rest; import retrofit2.Retrofit; import retrofit2.converter.gson.GsonConverterFactory; public class RetrofitClient { private static Retrofit retrofit = null; public static Retrofit getClient(String baseUrl) { if (retrofit==null) { retrofit = new Retrofit.Builder() .baseUrl(baseUrl) .addConverterFactory(GsonConverterFactory.create()) .build(); } return retrofit; } } |
4.Define 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<ApiResponse>.
Create ApiInterface.java under rest package.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
package com.vrinfosystem.retrofitdemo.rest; import com.vrinfosystem.retrofitdemo.model.ApiResponse; import retrofit2.Call; import retrofit2.http.Field; import retrofit2.http.FormUrlEncoded; import retrofit2.http.POST; public interface ApiInterface { @POST("retrofit.php") @FormUrlEncoded Call<ApiResponse> savePost(@Field("email") String email); } |
Looking at the ApiResponse class, we have a method called savePost(). On top of the method is the @POST annotation, which indicates that we want to execute a POST request when this method is called. The argument value for the @POST annotation is the endpoint—which is /posts. So the full URL will be
http://vrinfosystem.com/api/retrofit.php
Here, @FormUrlEncoded will indicates that the request will have its MIME type (a header field that identifies the format of the body of an HTTP request or response) set to application/x-www-form-urlencoded and also that its field names and values will be UTF-8 encoded before being URI-encoded. The @Field(“key”) annotation with parameter name should match the name that the API expects. Retrofit implicitly converts the values to strings using String.valueOf(Object), and the strings are then form URL encoded. null values are ignored.
5.Creating Api utility class
Create a class named ApiUtils under rest package.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
package com.vrinfosystem.retrofitdemo.rest; public class ApiUtils { private ApiUtils() {} public static final String BASE_URL = "http://vrinfosystem.com/api/"; public static ApiInterface getAPIService() { return RetrofitClient.getClient(BASE_URL).create(ApiInterface.class); } } |
This class has a base URL as a static variable,And it provides APiInterface with a getAPIService method.
6.Creating the Layout for MainActivity.
In activity_main.xml file we will have one EditText for Email ,and Submit button for posting data to the API.below the button,we will take LinearLayout with multiple textviews and ListView,for displaying our Post API response data.
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 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 |
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:paddingBottom="@dimen/activity_vertical_margin" tools:context="com.vrinfosystem.retrofitdemo.activity.MainActivity"> <EditText android:id="@+id/etEmail" android:layout_marginTop="14dp" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="@string/hint_email"/> <Button android:id="@+id/btnSubmit" android:layout_marginTop="14dp" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/colorAccent" android:textColor="@android:color/white" android:text="@string/action_submit"/> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="14dp" android:id="@+id/llResponse" android:visibility="gone" android:orientation="vertical"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textStyle="bold" android:padding="5dp" android:text="@string/company_name"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/tvCompanyName" android:padding="5dp" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textStyle="bold" android:padding="5dp" android:text="@string/country"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/tvCountry" android:padding="5dp" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textStyle="bold" android:padding="5dp" android:text="@string/state"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/tvState" android:padding="5dp" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textStyle="bold" android:padding="5dp" android:text="@string/city"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/tvCity" android:padding="5dp" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textStyle="bold" android:padding="5dp" android:text="@string/comapny_skills"/> <ListView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/listView" /> </LinearLayout> </LinearLayout> </LinearLayout> |
All the strings used in above layout are from string.xml under res->values folder.
1 2 3 4 5 6 7 8 9 10 11 |
<resources> <string name="app_name">RetrofitDemo</string> <string name="title">VR Info system </string> <string name="hint_email">Enter your Email here.</string> <string name="action_submit">Submit</string> <string name="company_name">Company Name :</string> <string name="country">Country :</string> <string name="state">State :</string> <string name="city">City :</string> <string name="comapny_skills">Company Skills :</string> </resources> |
7.Executing POST Request.
In the onCreate method of MainActivity we will intitalize instance of the ApiInteface and other necessary views of activity_main.xml.
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 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
package com.vrinfosystem.retrofitdemo.activity; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.text.TextUtils; import android.util.Log; import android.view.View; import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.EditText; import android.widget.LinearLayout; import android.widget.ListView; import android.widget.TextView; import com.vrinfosystem.retrofitdemo.R; import com.vrinfosystem.retrofitdemo.model.ApiResponse; import com.vrinfosystem.retrofitdemo.model.Message; import com.vrinfosystem.retrofitdemo.rest.ApiInterface; import com.vrinfosystem.retrofitdemo.rest.ApiUtils; import retrofit2.Call; import retrofit2.Callback; import retrofit2.Response; public class MainActivity extends AppCompatActivity { private static final String TAG = MainActivity.class.getSimpleName(); LinearLayout llResponse; String Email; ApiInterface mAPIService; TextView tvName,tvCountry,tvState,tvCity; ListView listView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); final EditText etEmail=(EditText) findViewById(R.id.etEmail); final Button btnSubmit=(Button) findViewById(R.id.btnSubmit); llResponse=(LinearLayout) findViewById(R.id.llResponse); tvName=(TextView) findViewById(R.id.tvCompanyName); tvCountry=(TextView) findViewById(R.id.tvCountry); tvState=(TextView) findViewById(R.id.tvState); tvCity=(TextView) findViewById(R.id.tvCity); listView=(ListView) findViewById(R.id.listView); mAPIService=ApiUtils.getAPIService(); btnSubmit.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Email=etEmail.getText().toString(); if(!TextUtils.isEmpty(Email)){ sendPost(Email); } } public void sendPost(String title) { mAPIService.savePost(Email).enqueue(new Callback<ApiResponse>() { @Override public void onResponse(Call<ApiResponse> call, Response<ApiResponse> response) { if(response.isSuccessful()) { Message message=response.body().getMsg(); setData(message); Log.i(TAG, "post submitted to API." + response.body().toString()); } } @Override public void onFailure(Call<ApiResponse> call, Throwable t) { Log.e(TAG, "Unable to submit post to API."); } }); } public void setData(Message message){ if (llResponse.getVisibility()==View.GONE){ llResponse.setVisibility(View.VISIBLE); } tvName.setText(message.getCompanyName()); tvCountry.setText(message.getCompanyCountry()); tvState.setText(message.getCompanyState()); tvCity.setText(message.getCompanyCity()); listView.setAdapter(new ArrayAdapter(MainActivity.this, android.R.layout.simple_list_item_1, message.getCompanySkills())); } }); } } |
We will call sendPost() method on click of submit button.In the sendPost(String) method used above,we will pass the Entered value of EditText etEmail . this method will call our API service interface method savePost(String)whose job is to execute a POST request sending the email to the API. The showResponse(String response) method will display the response on the screen.
Our APIService instance mAPIService method savePost(String) will return a Call instance which has a method called enqueue(Callback<T> callback).
enqueue() asynchronously sends the request and notifies your app with a callback when a response comes back. To use the enqueue() method, you have to implement two callback methods:
- onResponse(): invoked for a received HTTP response. To get the status code in order for you to handle situations based on them, you can use the method response.code(). You can also use the isSuccessful() method to find out if the status code is in the range 200-300, indicating success.
-
onFailure(): invoked when a network exception occurred communicating to the server or when an unexpected exception occurred handling the request or processing the response.
Step 10.Run your App
FinallyYou can Run the App,after entering email in EditText field.Then click on submit button and It displays Response from the API in respected fields.So,Your final output will be: