Retrofit
Retrofit is a REST Client for Android and Java developed by Square. It makes it relatively easy to retrieve and upload JSON (or other structured data) via a REST based webservice. In Retrofit you configure which converter is used for the data serialization. Typically for JSON you use GSon, but you can add custom converters to process XML or other protocols. Retrofit uses the OkHttp library for HTTP requests.
Get GITHUB code from here.
Using Retrofit
To work with Retrofit you need basically three classes.
- Model class which is used to map the JSON data.
- Builder class – Instance which uses the interface and the Builder API which allows defining the URL end point for the HTTP operation.
- Interfaces which defines the possible HTTP operations.
Getting Cric API Key / Sample JSON
In this tutorial we will use The Cric API. In order to use this API it is necessary to obtain the API key. Here you need to register and login in order to obtain the key.
This is the Json format provided by the Cric API under MatchCalender.
Extended form of above Json.
Creating New Project
- 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.
- Open build.gradle and add Retrofit, Gson dependencies.
build.gradle
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:26.1.0'
//retrofit,json
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.
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.lenovo.cricketmatchapp">
<uses-permission android:name="android.permission.INTERNET"/>
<application
android:allowBackup="true"
android:icon="@drawable/ic_ball"
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.
Creating Model Class
Using this route (http://www.cricapi.com/api/matchCalendar/?apikey=INSERT_YOUR_API_KEY) we get the total matches of this year.
In this Json format data[ ] is the array of object consists of unique_id,name,date.
5.Create a class named CalenderResponse.java and MatchCalender.java under model package.
CalenderResponse.java
package com.example.lenovo.cricketmatchapp.model; import com.google.gson.annotations.SerializedName; import java.util.List; public class CalenderResponse { @SerializedName("data") private List<MatchCalender> data; public List<MatchCalender> getData() { return data; } public void setData(List<MatchCalender> data) { this.data = data; } }
MatchCalender.java
package com.example.lenovo.cricketmatchapp.model; import com.google.gson.annotations.SerializedName; public class MatchCalender { @SerializedName("unique_id") private String uniqueId; @SerializedName("name") private String name; @SerializedName("date") private String date; public MatchCalender(String uniqueId, String name, String date) { this.uniqueId = uniqueId; this.name = name; this.date = date; } public String getUniqueId() { return uniqueId; } public void setUniqueId(String uniqueId) { this.uniqueId = uniqueId; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getDate() { return date; } public void setDate(String date) { this.date = date; } }
Creating the Retrofit instance
6. 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.
ApiClient. java
package com.example.lenovo.cricketmatchapp.rest; import retrofit2.Retrofit; import retrofit2.converter.gson.GsonConverterFactory; public class ApiClient { public static final String BASE_URL = "http://cricapi.com/"; public static Retrofit retrofit = null; public static Retrofit getClient() { if (retrofit == null) { retrofit = new Retrofit.Builder() .baseUrl(BASE_URL) .addConverterFactory(GsonConverterFactory.create()) .build(); } return retrofit; } }
Defining endpoints inside of an interface
The endpoints are defined inside of an interface using special retrofit annotations to encode details about the parameters and request method. Interfaces defines the possible HTTP operations
7.Create ApiInterface.java under rest package.
So, using this route the retrofit will generate the following URL:
http://www.cricapi.com/api/matchCalendar/?apikey=INSERT_YOUR_API_KEY
ApiInterface.java
package com.example.lenovo.cricketmatchapp.rest; import com.example.lenovo.cricketmatchapp.model.CalenderResponse; import retrofit2.Call; import retrofit2.http.GET; import retrofit2.http.Query; public interface ApiInterface { @GET("api/matchCalendar") Call<CalenderResponse> getMatchCalender(@Query("apikey") String apiKey); }
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
Making the Request
8.Let’s make the request from our MainActivity. Open the MainActivity.java and do the below changes. Make sure that your replaced API_KEY should be correct.
MainActivity.java
package com.example.lenovo.cricketmatchapp.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 com.example.lenovo.cricketmatchapp.R; import com.example.lenovo.cricketmatchapp.adapter.MatchCalenderAdapter; import com.example.lenovo.cricketmatchapp.model.CalenderResponse; import com.example.lenovo.cricketmatchapp.model.MatchCalender; import com.example.lenovo.cricketmatchapp.rest.ApiClient; import com.example.lenovo.cricketmatchapp.rest.ApiInterface; import java.util.List; import retrofit2.Call; import retrofit2.Callback; import retrofit2.Response; public class MainActivity extends AppCompatActivity { private final static String API_KEY = "kAv1Vdcj8teYg5QnVmAACIofzdg2"; private static final String TAG = MainActivity.class.getSimpleName(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ApiInterface apiService = ApiClient.getClient().create(ApiInterface.class); Call<CalenderResponse> call = apiService.getMatchCalender(API_KEY); call.enqueue(new Callback<CalenderResponse>() { @Override public void onResponse(Call<CalenderResponse> call, Response<CalenderResponse> response) { int statuscode = response.code(); List<MatchCalender> matchlist = response.body().getData(); } @Override public void onFailure(Call<CalenderResponse> call, Throwable t) { 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.
Displaying the Results in RecyclerView
9.Let’s use RecyclerView for fetched results. First of all, add it to the build.gradle.
build.gradle
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:26.1.0'
//recyclerView
compile 'com.android.support:recyclerview-v7:26.1.0'
}
10.Create a layout named match_calender_item.xml under res layout.
match_calender_item.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" android:background="@drawable/bg_color" > <TextView android:id="@+id/date" android:padding="5dp" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_marginBottom="10dp" android:layout_marginRight="20dp" android:layout_marginTop="8dp" android:textColor="@color/colorPrimaryDark" android:textSize="20sp" android:textStyle="bold" /> <TextView android:id="@+id/name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:padding="5dp" android:layout_marginBottom="8dp" android:textAllCaps="true" android:textColor="@android:color/white" android:textSize="20sp" android:textStyle="bold" /> </LinearLayout>
11.Adapter is a common pattern which helps to bind view and data, so let’s implement adapter for this.
Create a class named MatchCalenderAdapter.java under adapter package.
MatchCalenderAdapter.java
package com.example.lenovo.cricketmatchapp.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.TextView; import com.example.lenovo.cricketmatchapp.R; import com.example.lenovo.cricketmatchapp.model.MatchCalender; import java.util.List; public class MatchCalenderAdapter extends RecyclerView.Adapter<MatchCalenderAdapter.MatchCalenderViewHolder> { List<MatchCalender> matchlist; Context context; public static class MatchCalenderViewHolder extends RecyclerView.ViewHolder { TextView name; TextView date; public MatchCalenderViewHolder(View v) { super(v); name = (TextView) v.findViewById(R.id.name); date = (TextView) v.findViewById(R.id.date); } } public MatchCalenderAdapter(List<MatchCalender> matchlist, Context context) { this.matchlist = matchlist; this.context = context; } @Override public void onBindViewHolder(MatchCalenderViewHolder holder, int position) { holder.date.setText(matchlist.get(position).getDate()); holder.name.setText(matchlist.get(position).getName()); } @Override public MatchCalenderAdapter.MatchCalenderViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.match_calender_item, parent, false); return new MatchCalenderViewHolder(view); } @Override public int getItemCount() { return matchlist.size(); } }
12.Open MainActivity. java and modify the code as below.
MainActivity. java
package com.example.lenovo.cricketmatchapp.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 com.example.lenovo.cricketmatchapp.R; import com.example.lenovo.cricketmatchapp.adapter.MatchCalenderAdapter; import com.example.lenovo.cricketmatchapp.model.CalenderResponse; import com.example.lenovo.cricketmatchapp.model.MatchCalender; import com.example.lenovo.cricketmatchapp.rest.ApiClient; import com.example.lenovo.cricketmatchapp.rest.ApiInterface; import java.util.List; import retrofit2.Call; import retrofit2.Callback; import retrofit2.Response; public class MainActivity extends AppCompatActivity { private final static String API_KEY = "kAv1Vdcj8teYg5QnVmAACIofzdg2"; private static final String TAG = MainActivity.class.getSimpleName(); RecyclerView recyclerView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); recyclerView = (RecyclerView) findViewById(R.id.match_calender_recycler_view); recyclerView.setLayoutManager(new LinearLayoutManager(this)); ApiInterface apiService = ApiClient.getClient().create(ApiInterface.class); Call<CalenderResponse> call = apiService.getMatchCalender(API_KEY); call.enqueue(new Callback<CalenderResponse>() { @Override public void onResponse(Call<CalenderResponse> call, Response<CalenderResponse> response) { int statuscode = response.code(); List<MatchCalender> matchlist = response.body().getData(); recyclerView.setAdapter(new MatchCalenderAdapter(matchlist, getApplicationContext())); } @Override public void onFailure(Call<CalenderResponse> call, Throwable t) { Log.e(TAG, t.toString()); } }); } }
Now when you run the app it will look like this:
Thanks for such good explanation.
From where I can get the full source code.
get it from github there is link on the top.