What is Retrofit and how to use Retrofit in Android?

Retrofit is type safe REST client for Android.  it make simple to call RESTfull services in Android.
Today we are going to learn Retrofit2 in this post.

Retrofit uses OkHttp for making Http requests. Retrofit easily convets JSON data inot POJO classes. For this conversion we need to pass Converters to Retrofit object.
Before start we should have to know about below points

  • Converters
  • Interceptors

Converters: Convert the JSON data into related POJO class.
Retrofit will support below converters

  • Gson    com.squareup.retrofit2:converter-gson:2.8.5
  • Jackson    com.squareup.retrofit2:converter-jackson:2.6.2
  • Moshi    com.squareup.retrofit2:converter-moshi:2.1.0
  • Protobuf    com.squareup.retrofit2:converter-protobuf:2.6.2
  • Wire    com.squareup.retrofit2:converter-wire:2.6.2
  • Simple XML    com.squareup.retrofit2:converter-simplexml:2.6.2

Interceptors: Interceptors are mechanism available in OkHttp to monitor, rewrite, and retry the calls for each request.

These are defined as below
Application Interceptors:  To make application for Application Interceptors we need to add addInterceptor() to retrofit object.
Network Interceptors: TO make application for Network Interceptors we need to add addNetworkInterceptor() to retrofit object

To Implement code we need to follow below steps.

Add Related Dependencies

implementation 'com.squareup.retrofit2:retrofit:2.6.1'
implementation 'com.google.code.gson:gson:2.8.5'
implementation 'com.squareup.retrofit2:converter-gson:2.8.5'
implementation 'com.jakewharton:butterknife:10.2.0'
annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.0'

Here i have used ButterKnofe for ViewInjection


2) Create Retrofit Object

OkHttpClient client = new OkHttpClient.Builder().build();
Retrofit retrofit=new Retrofit.Builder()
                .baseUrl(PASS_HERE_BASE_URL)
                .addConverterFactory(GsonConverterFactory.create())
                .client(client)
                .build();

 

If we want to add Interceptors

HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient client = new OkHttpClient.Builder().
addInterceptor(interceptor).build();

 

Here we created Retrofit object with our API base URL

3) Create Client Interface

Create an interface with required API methods.
Retrofit provides the list of annotations for each HTTP methods.
Example @GET,@POST,@PUT,@DELETE, @PATH...
Lets check our Client interface code

import retrofit2.Call;
import retrofit2.http.Body;
import retrofit2.http.Field;
import retrofit2.http.FormUrlEncoded;
import retrofit2.http.GET;
import retrofit2.http.POST;
import retrofit2.http.Query;

interface ServiceCall {

    @GET("api/classes.php")
    CallgetClasses();
}

 

Here we are using the POST method to get the Response data.
ResultData is my POJO class.
We can create POJO classes based on our response data

Just copy your response data and paste into JSON To POJO  window, This will create repected POJO classes

We have different ways to send reauest params to API.

  • @Filed - This request need @FormUrlEncoded, This is only  work for GET Method
  • @Query - We can add method params as Query
  • @Body - We can send Method params as Body, This contains object like POSJO object, JSON Objects...
  • @Url - Will use dynamic URLS.

4) Use Retrofit Object and call API in Activity

ServiceCall call = retrofit.create(ServiceCall.class);
      
        Call request = call.getClasses();
        request.enqueue(new Callback() {
            @Override
            public void onResponse(Call call, Response response) {
                

                if (response.isSuccessful()) {
                    
                }
                
            }

            @Override
            public void onFailure(Call call, Throwable t) {
                Log.v("Error  ", "Error  " + t.getMessage());
                
            }
        });
        

In the Resposne GsonConverter automatically convert JSON resposne to Respected POJO classes.
 Here the ResultData will be the POJO for the Classes Response.
        
 Let see complete code.

ClassListActivity.java

public class ClassListActivity extends AppCompatActivity {

    @BindView(R.id.recyclerview)
    RecyclerView recyclerview;
    @BindView(R.id.txt_nodata)
    CustomTextview txtNodata;

    ClassAdapter classAdapter;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_class_list);
        ButterKnife.bind(this);
        classAdapter=new ClassAdapter();
        recyclerview.setLayoutManager(new LinearLayoutManager(this,RecyclerView.VERTICAL,false));
        recyclerview.setAdapter(classAdapter);
        callAPI();
    }

    private void callAPI() {

        Retrofit retrofit = new Retrofit.Builder()
                .addConverterFactory(GsonConverterFactory.create(new GsonBuilder()
                        .setLenient()
                        .create()))
                .baseUrl(ServiceCall.BASE_IRL)
                .build();
        ServiceCall call = retrofit.create(ServiceCall.class);
        CustomDialog.showDialog(ClassListActivity.this, true);
        Call request = call.getClasses();
        request.enqueue(new Callback() {
            @Override
            public void onResponse(Call call, Response response) {
                CustomDialog.closeDialog();

                if (response.isSuccessful()) {
                    List listCalsses = response.body().getClasses();

                    classAdapter.addClasses(listCalsses);
                }
                if(classAdapter.getItemCount()>0)
                    txtNodata.setVisibility(View.GONE);
                else txtNodata.setVisibility(View.VISIBLE);
            }

            @Override
            public void onFailure(Call call, Throwable t) {
                Log.v("Error  ", "Error  " + t.getMessage());
                CustomDialog.closeDialog();
            }
        });
    }

    @OnClick({R.id.recyclerview, R.id.txt_nodata})
    public void onViewClicked(View view) {
        switch (view.getId()) {
            case R.id.recyclerview:
                break;
            case R.id.txt_nodata:
                break;
        }
    }
}

activity_class_list.xml


    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=".ClassListActivity">
            android:id="@+id/recyclerview"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

   
            android:id="@+id/txt_nodata"
        android:layout_width="match_parent"
        android:gravity="center"
        android:text="No Classes Found!"
        android:visibility="gone"
        android:layout_height="match_parent" />

 

 

 

ClassAdapter.java

 

public class ClassAdapter extends RecyclerView.Adapter {

    ListlistClass;
    public ClassAdapter(){
        listClass=new ArrayList<>();
    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        return

new  ViewHolder(LayoutInflater.from(parent.getContext()).

 

inflate(R.layout.class_layout_item, parent, false));
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, int position) {


        String name=listClass.get(position).getName();
        holder.userName.setText(name);
        holder.txtClass.setText(name.substring

(0,name.indexOf(" ")));
    }

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

    public void addClasses(Listclasses)
    {
        listClass.clear();
       for(Classes cls:classes)
        addClass(cls);

    }
    public void addClass(Classes cls)
    {
        listClass.add(cls);
        notifyItemInserted(listClass.size()-1);
    }

    static
    class ViewHolder extends RecyclerView.ViewHolder {
        @BindView(R.id.img_class)
        ImageView imgClass;
        @BindView(R.id.txt_class)
        CustomTextview txtClass;
        @BindView(R.id.rel_pro)
        RelativeLayout relPro;
        @BindView(R.id.user_name)
        CustomTextview userName;
        public ViewHolder(@NonNull View itemView) {
            super(itemView);
            ButterKnife.bind(this, itemView);
        }
    }


}

 

class_layout_item.xml


    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="@dimen/_2dp"
    app:cardCornerRadius="@dimen/_5dp"

    >
            android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:minHeight="?attr/actionBarSize"
        android:layout_margin="@dimen/_5dp"
        >
            android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:layout_weight="1">
                    android:id="@+id/rel_pro"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical">

                            android:id="@+id/img_class"
                android:layout_width="50dp"
                android:layout_height="50dp"
                android:layout_centerHorizontal="true"
                android:src="@drawable/circular_profile"
                />

                            android:id="@+id/txt_class"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerHorizontal="true"
                android:layout_centerVertical="true"
                android:gravity="center_vertical|center_horizontal|center"
                android:text="U"

                android:textColor="@color/white"
                />
       
                    android:id="@+id/user_name"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
            android:layout_centerVertical="true"
            android:gravity="center_vertical"
            android:text="uername"
            android:textSize="22sp"
            android:textColor="@color/colorPrimary"
            android:textStyle="bold"
            android:layout_marginStart="@dimen/_16sp"
            android:layout_toEndOf="@+id/rel_pro"
            />

   
   

 

 

 

POJO Classes

public class ResultData {
    @SerializedName("error")
    @Expose
    private Boolean error;
    @SerializedName("message")
    @Expose
    private String message;

    @SerializedName("data")
    @Expose
    private List ClassSubjects;

    public Boolean getError() {
        return error;
    }

    public void setError(Boolean error) {
        this.error = error;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
    public List  getClasses() {
        return ClassSubjects;
    }

    public void setUser(List user) {
        this.ClassSubjects = user;
    }
}

 

public class Classes implements ClassSubjects {
    @SerializedName("id")
    @Expose
    private String id;
    @SerializedName("name")
    @Expose
    private String name;

    public boolean isSelected = false;
    public String getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
    public boolean isSelected() {
        return isSelected;
    }

    public void setSelected(boolean selected) {
        isSelected = selected;
    }

}