Table of Contents
- Why to use Retrofit rather than Volley or AsyncTask.
- Source code:
- Step 1 :Creating Project
- Step 2 : Add Retrofit and json gradle dependency
- Step 3 : Creating Layout
- Step 4: Creating layout for Row
- Step 5 : Creating model object Country :
- Step 6: Creating BaseAdapter for ListView
- Step 7 : Creating interface for making HTTP call using Retrofit.
- Step 8 : Creating MainActivity
- Step 8: Add internet permission in AndroidManifest.xml
- Put it in AndroidManifest.xml
- Step 9 : Running the app
In previous post, we have seen android JSON parsing tutorial which was very simple.
If you are not aware about Retrofit, it is android http library used to handle HTTP request.You can treat it as a replacement of AsyncTask in previous tutorial.
Why to use Retrofit rather than Volley or AsyncTask.
Example :
I have already implemented restful webservices json example. I am going to use same json response for rendering it in custom listview.
You can use below link.
https://cdn.rawgit.com/arpitmandliya/AndroidRestJSONExample/master/countries.json
You will get below Json response from above URL:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
[ { "id":1, "countryName":"India" }, { "id":4, "countryName":"China" }, { "id":3, "countryName":"Nepal" }, { "id":2, "countryName":"Bhutan" } ] |
We are getting above JSONArray from rest web service. If you are not familiar with JSON, you can go through Json tutorial. We are going to render above JSON response to android custom listview as below:
Lets code this example now:
Source code:
Step 1 :Creating Project
Create an android application project named “RetrofitAndroidExample”.
Step 2 : Add Retrofit and json gradle dependency
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 |
apply plugin: 'com.android.application' android { compileSdkVersion 25 buildToolsVersion "25.0.0" defaultConfig { applicationId "com.java2blog.retrofitandroidexample" minSdkVersion 15 targetSdkVersion 25 versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } } dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { exclude group: 'com.android.support', module: 'support-annotations' }) compile 'com.android.support:appcompat-v7:25.0.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' testCompile 'junit:junit:4.12' } |
Step 3 : Creating Layout
Change res ->layout -> activity_main.xml as below:
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 |
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="10dp" tools:context="com.java2blog.retrofitandroidexample.MainActivity"> <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Fetching countries data" android:id="@+id/btnSubmit" /> <ListView android:id="@+id/android:list" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@id/btnSubmit" /> </RelativeLayout> |
We have one button and listview. When you click the button, we are going to populate data in listview by calling restful web services and render it on the listview.
Step 4: Creating layout for Row
- Go to res -> layout
- right click on layout
- Click on New -> File.
- Create a file named “row_item.xml” and paste below code in row_item.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 |
<?xml version="1.0" encoding="utf-8"?> <GridLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_columnWeight="1" android:layout_marginLeft="10dp" android:textSize="30dp" android:textColor="#1E90FF" android:id="@+id/textViewId" android:layout_row="0" android:layout_column="1" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_columnWeight="1" android:layout_marginLeft="10dp" android:textSize="20dp" android:textColor="#4B0082" android:id="@+id/textViewCountry" android:layout_row="1" android:layout_column="1" /> </GridLayout> |
Step 5 : Creating model object Country :
If you notice, we are getting Json array from restful web service which has 4 items. Each item have two attributes id and countryName. We are going to create country object for each item.
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 |
package com.java2blog.androidrestjsonexample; public class Country{ int id; String countryName; public Country(int i, String countryName) { super(); this.id = i; this.countryName = countryName; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getCountryName() { return countryName; } public void setCountryName(String countryName) { this.countryName = countryName; } } |
Step 6: Creating BaseAdapter for ListView
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 |
package com.java2blog.androidrestjsonexample; import android.app.Activity; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.TextView; import com.java2blog.androidrestjsonexample.Country; import com.java2blog.androidrestjsonexample.R; import java.util.ArrayList; public class CustomCountryList extends BaseAdapter { private Activity context; ArrayList countries; public CustomCountryList(Activity context, ArrayList countries) { // super(context, R.layout.row_item, countries); this.context = context; this.countries=countries; } public static class ViewHolder { TextView textViewId; TextView textViewCountry; } @Override public View getView(int position, View convertView, ViewGroup parent) { View row=convertView; LayoutInflater inflater = context.getLayoutInflater(); ViewHolder vh; if(convertView==null) { vh=new ViewHolder(); row = inflater.inflate(R.layout.row_item, null, true); vh.textViewId = (TextView) row.findViewById(R.id.textViewId); vh.textViewCountry = (TextView) row.findViewById(R.id.textViewCountry); // store the holder with the view. row.setTag(vh); } else { vh = (ViewHolder) convertView.getTag(); } vh.textViewCountry.setText(countries.get(position).getCountryName()); vh.textViewId.setText(""+countries.get(position).getId()); return row; } public long getItemId(int position) { return position; } public Object getItem(int position) { return position; } public int getCount() { if(countries.size()<=0) return 1; return countries.size(); } } |
Step 7 : Creating interface for making HTTP call using Retrofit.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
package com.java2blog.retrofitandroidexample; import java.util.List; import retrofit2.Call; import retrofit2.Callback; import retrofit2.http.GET; public interface CountryArrayAPI { /* @GET url is after Base_URL. We are going to get List of country as response. */ @GET("/arpitmandliya/AndroidRestJSONExample/master/countries.json") public Call<List> getCountries(); } |
Step 8 : Creating MainActivity
Steps for Retrofit call :
- Create retrofit instance using base url. Retrofit will implicitly use gson to convert JSON to corresponding object. You need to define gson library explicitly in Retrofit 2.0
123456Retrofit retrofit = new Retrofit.Builder().baseUrl(BASE_URL).addConverterFactory(GsonConverterFactory.create()).build(); - Create api with retrofit’s create method and call getCountries method.
1234CountryArrayAPI api = retrofit.create(CountryArrayAPI.class);Call<List> call = api.getCountries(); - Enqueue the request and onResponse will get called if your call is successful else onFailure will get called.
Change src/main/packageName/MainActivity.java as below:
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 |
package com.java2blog.retrofitandroidexample; import android.util.Log; import android.app.Activity; import android.app.ProgressDialog; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.view.View; import android.widget.AdapterView; import android.widget.Button; import android.widget.ListView; import android.widget.Toast; import java.util.ArrayList; import java.util.List; import retrofit2.Call; import retrofit2.Callback; import retrofit2.Response; import retrofit2.Retrofit; import retrofit2.converter.gson.GsonConverterFactory; public class MainActivity extends AppCompatActivity { private Button btnSubmit; String responseText; Activity activity; ArrayList countries=new ArrayList(); private ProgressDialog progressDialog; ListView listView; //Base URL of our web service public static final String BASE_URL = "https://cdn.rawgit.com"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); activity = this; btnSubmit = (Button) findViewById(R.id.btnSubmit); listView = (ListView) findViewById(android.R.id.list); btnSubmit.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { countries.clear(); progressDialog = new ProgressDialog(MainActivity.this); progressDialog.setMessage("Fetching countries data"); progressDialog.setCancelable(false); progressDialog.show(); //Call WebService getWebServiceResponseData(); } }); } protected Void getWebServiceResponseData() { //Creating Retrofit rest adapter Retrofit retrofit = new Retrofit.Builder() .baseUrl(BASE_URL) .addConverterFactory(GsonConverterFactory.create()) .build(); //Creating an object of our api interface CountryArrayAPI api = retrofit.create(CountryArrayAPI.class); Call<List> call = api.getCountries(); call.enqueue(new Callback<List>() { @Override public void onResponse(Call<List> call, Response<List> response) { try { countries= (ArrayList)response.body(); if (progressDialog.isShowing()) progressDialog.dismiss(); // For populating list data CustomCountryList customCountryList = new CustomCountryList(activity, countries); listView.setAdapter(customCountryList); listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) { Toast.makeText(getApplicationContext(),"You Selected "+countries.get(position).getCountryName()+ " as Country",Toast.LENGTH_SHORT).show(); } }); } catch (Exception e) { Log.d("onResponse", "There is an error"); e.printStackTrace(); } } @Override public void onFailure(Call<List> call, Throwable t) { Log.d("Failure",t.toString()); } }); return null; } } |
Step 8: Add internet permission in AndroidManifest.xml
Copy following code:
1 2 3 |
<uses-permission android:name="android.permission.INTERNET" /> |
Put it in AndroidManifest.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.java2blog.retrofitandroidexample"> <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=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest> |
Step 9 : Running the app
When you run the app, you will get below screen:
When you click on above button, you will get below screen.
We are done with Android Retrofit tutorial. If you are facing any issue, please comment.