Volley & Retrofit Kotlin 2019–20 | BulletTut
To-the-point comparison with very basic implementation to get started
Nov 5 · 6 min read

Tutorial Content
Volley Intro
Retrofit Intro
Volley and Retrofit difference
Project Setup
Volley Implementation(Basic)
Retrofit Implementation(Basic)
Volley Intro
- Developed by Google and introduced during Google I/O 2013.
- Part of the Android Open Source Project(AOSP).
- Manages the processing and caching of network requests.
Retrofit Intro
- Developed by Square.
- A type-safe HTTP client for Android and Java.
- Uses OkHttp as the systems administration layer and is based over it.
Volley and Retrofit differences
1. In-Built Request Types
Volley:
- StringRequest– Returned data is parsed and converted into a String.
- JsonObjectRequest– Converts the response into a JSONObject.
- JsonArrayRequest– Response is automatically converted into a JSONArray.
- ImageRequest– Request converts the response into a decoded bitmap automatically.
Retrofit:
- Boolean– Web API response needs to be a String boolean.
- Integer– Web API response needs to be an integer.
- Date– Web API response should be Long format date.
- String– Web API response needs to be in String format.
- Object– Web API response needs to be in a JSON object.
- Collections– Web API response needs to be in a String Format.
2. Retry Mechanism
Volley:
- Supports retries on request timeout.
- Can set a retry policy by using the setRetryPolicy() method.
- By default, a volley request timeout time is set to 5 seconds and can be customized.
Retrofit:
- Does not come with retry support by default.
- Have to check for failure, clone and enqueue the call manually for each network call.
3. Caching
Volley:
- Has a very elaborate caching mechanism.
- Customizable caching functionality to support your requirements.
Retrofit:
- Caching not supported by default.
- Can implement RFC 2616 caching which is the spec for HTTP caching, through the OkHttpClient.
4. Loading Images
Volley:
- Has a special type of request to get images from a network called ImageRequest.
- Supports the resizing of the returned image in the worker thread itself.
- Also has a NetworkImageView class which can be used with ImageLoader class, to automatically load images, whenever the NetworkImageViewappears.
Retrofit:
- Does not support the loading of images by default.
- Can be combined with OkHttpClient to support the loading of images.
5. Data Parsing
Volley:
- The entire network call + JSON/XML parsing is completely handled with help from Gson for JSON parsing.
- Support for arbitrary formats with pluggable serialization/deserialization.
Retrofit:
- Need to include this GsonRequest<T> class, which represents a request whose response is converted to type T by Gson.
Project Setup
- Complete source code in the following link: https://github.com/karanjatav/RestApisLibs
- Fetch data from a fake online REST API with the following URL that will be displayed in the app: https://jsonplaceholder.typicode.com/posts/1

- Create a new project in Android Studio.
- Select “Empty Activity” press next.

- Name the project “RestApisLibs”.
- Select Language as Kotlin.
- Leave rest as default and press next.

- Add Internet Permission in AndroidManifest.xml file.
<uses-permission android:name=”android.permission.INTERNET” /><application...- Replace the following code in activity_main.xml :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:orientation="vertical"
android:padding="5dp"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:id="@+id/tvResponseFrom"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/tvUserId"
android:layout_marginTop="5dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/tvId"
android:layout_marginTop="5dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/tvTitle"
android:layout_marginTop="5dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/tvBody"
android:layout_marginTop="5dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>- Add a string url at the beginning of the MainActivity.kt.
private val baseUrl = "https://jsonplaceholder.typicode.com/posts/"- Declare all the TextViews.
private lateinit var tvResponseFrom: TextView
private lateinit var tvUserId: TextView
private lateinit var tvId: TextView
private lateinit var tvTitle: TextView
private lateinit var tvBody: TextView- Connect TextViews from the XML file in onCreate function.
setContentView(R.layout.activity_main)
tvResponseFrom = findViewById(R.id.tvResponseFrom)
tvUserId = findViewById(R.id.tvUserId)
tvId = findViewById(R.id.tvId)
tvTitle = findViewById(R.id.tvTitle)
tvBody = findViewById(R.id.tvBody)- Create a function called setTextViews to set up the TextViews as data comes in.
private fun setTextViews(
responseFrom: String,
userId: String,
id: String,
title: String,
body: String
) {
tvResponseFrom.text = "Response via = $responseFrom"
tvUserId.text = "UserId = $userId"
tvId.text = "Id = $id"
tvTitle.text = "Title= $title"
tvBody.text = "Body = $body"
}Volley Implementation(Basic)
- Add the dependency in build.gradle(app) file and sync.
dependencies {
....implementation 'com.android.volley:volley:1.1.1'....
}
- In MainActivity.kt create a function getVolleyResponse() for API calling through Volley:
private fun getVolleyResponse() {
val queue = Volley.newRequestQueue(this) //...1
val stringRequest = StringRequest(
Request.Method.GET,
baseUrl+1,
Response.Listener<String> { response -> },
Response.ErrorListener { }) //...2
queue.add(stringRequest) //...3
}- Create a request queue.
- Create a stringRequest adding method, URL, Response.Listener, Response.ErrorListener.
- Add the request to the queue.
- Handle response inside Response listeners.
val stringRequest = StringRequest(
Request.Method.GET,
baseUrl+1,
Response.Listener<String> { response ->
Log.d("Response", response)
tvResponseFrom.text = "Response From Volley"
try {
val jsonOutPut = JSONObject(response)
setTextViews(
"Volley",
jsonOutPut.getString("userId"),
jsonOutPut.getString("id"),
jsonOutPut.getString("title"),
jsonOutPut.getString("body")
)
} catch (e: JSONException) {
Log.d("Parsing Issue:", e.localizedMessage)
tvResponseFrom.text = "Parsing Issue"
}
}, //...3
Response.ErrorListener { tvResponseFrom.text = "Response fail" }) //...44. Parse the response inside Response.Listener.
5. Set text of tvResponseFrom in Response.ErrorListener in case of faliure.
- Add the function in onCreate method at the bottom.
override fun onCreate(savedInstanceState: Bundle?) {
...
getVolleyResponse()
}- Run the app.

Retrofit Implementation(Basic)
- Add the dependencies in build.gradle(app) file and sync.
dependencies {
....def retrofitVersion = "2.6.1"
implementation "com.squareup.retrofit2:retrofit:$retrofitVersion"
implementation "com.squareup.retrofit2:converter-gson:$retrofitVersion"....
}
- Create a file Post.kt and add the following code:
data class Post(
var userId: Int = 0,
var id: Int? = null,
var title: String? = null,
var body: String? = null
)- Create a file JsonPlaceHolder.kt and add the following code:
interface JsonPlaceHolderApi {
@GET("1")
fun getPosts(): Call<Post>
}- In MainActivity.kt create a function getRetrofitResponse() for API calling through Retrofit:
private fun getRetrofitResponse() {
val retrofit = Retrofit.Builder()
.baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create())
.build() //...1
val jsonPlaceHolderApi = retrofit.create(JsonPlaceHolderApi::class.java) //...2
val postApi = jsonPlaceHolderApi.getPosts() //...3
postApi.enqueue(object : Callback<Post> {
override fun onResponse(call: Call<Post>, response: retrofit2.Response<Post>) {}
override fun onFailure(call: Call<Post>, t: Throwable) {}
}) //...4
}- Create a Retrofit.Builder instance and implement methods like baseUrl(), addConverterFactory(), build().
- Create JsonPlaceHolderApi instance.
- Call a method getPosts() through jsonPlaceHolderApi and put the result in postApi value.
- Call enqueue method on postApi and with a Callback<Post> object as a parameter.
- Handle listeners in Callback<Post> object.
call.enqueue(object : Callback<Post> {
override fun onResponse(call: Call<Post>, response: retrofit2.Response<Post>) {
if (!response.isSuccessful) {
tvResponseFrom.text = "Code " + response.code()
return
}
val post = response.body()
if (post != null) {
setTextViews(
"Retrofit",
post.userId.toString(),
post.id.toString(),
post.title!!,
post.body!!
)
}
} //...5
override fun onFailure(call: Call<Post>, t: Throwable) {
tvResponseFrom.text = "Response fail"
} //...6
})5. Check if the response gives a proper HTTP code and extract the data from it.
6. Set tvResponseFrom text in case of a failure.
- Add the function in onCreate method at the bottom.
override fun onCreate(savedInstanceState: Bundle?) {
...
getRetrofitResponse()
}- Run the app.

- Check out the complete source code in the following link: https://github.com/karanjatav/RestApisLibs