Retrofit in Android
Why are we using Retrofit?
We are using Retrofit because we are not allowed to perform network calls on main thread after the Android version Honeycomb.
What is Retrofit?
Retrofit is a HTTP networking library that is used for Android and Java and it is type-safe.
Type of converters used in Retrofit
- GSON
- Jackson
- Moshi
- Wire
- Simple XML etc.
Can you create a Custom Converter?
- Yes we can create a custom converter with the help of Converter.Factory class. Once created we can use the instance this class in our adapter.
Follow these steps to use Retrofit.
- Add the required dependency in buld.gradle file (Module)
- Add internet permission in Android.Manifest.xml file.
- Design the user interface to show the response on the screen.
- Create a Model class.
- Establish a connection with Retrofit and create the request.
- Dependencies used for Retrofit:
def retrofit_version = "2.9.0"
implementation "com.squareup.retrofit2:retrofit:$retrofit_version"
implementation "com.squareup.retrofit2:converter-gson:$retrofit_version"
implementation "com.squareup.okhttp3:logging-interceptor:4.9.1"
- Permission added in Android.Manifest.xml file:
<uses-permission android:name="android.permission.INTERNET" />
- Define the Model class.
class Post(val userId : Int , val id : Int? , val title : String , @SerializedName("body") val text : String)
{
constructor(userIdParam : Int , titleParam : String , bodyParam : String) : this(userIdParam , null , titleParam , bodyParam)
}
- Define the GET and POST requests in an Interface
interface JSONPlaceholderAPI
{
// Calling this URL https://jsonplaceholder.typicode.com/posts to get posts.
// This part (https://jsonplaceholder.typicode.com/) of the URL can be declared as baseURL
@GET("posts")
fun getPosts() : Call<List<Post>>
// https://jsonplaceholder.typicode.com/comments?postId=1
@GET("comments")
fun getCommentsWithPostId(@Query("postId") postId : Int) : Call<List<Comment>>
// https://jsonplaceholder.typicode.com/posts/1/comments
@GET("posts/{id}/comments")
fun getComments(@Path("id") postId : Int) : Call<List<Comment>>
// https://jsonplaceholder.typicode.com/comments?postId=1&_sort=id&_order=asc
@GET("comments")
fun getSortedCommentsWithPostId(@Query("postId") postId : Int? , @Query("_sort") sort : String? , @Query("_order") order : String?) : Call<List<Comment>>
// https://jsonplaceholder.typicode.com/comments?postId=1&postId=3&postId=5&_sort=id&_order=null
@GET("comments")
fun getSortedCommentsWithPostIds(@Query("postId") postIds : List<Int>? , @Query("_sort") sort : String? , @Query("_order") order : String?) : Call<List<Comment>>
// https://jsonplaceholder.typicode.com/comments?_order=asc&postId=1&_sort=id
@GET("comments")
fun getSortedCommentsWithParameters(@QueryMap parameters : Map<String , String>) : Call<List<Comment>>
// https://jsonplaceholder.typicode.com/posts/1/comments
@GET
fun getCommentsWithURL(@Url url : String) : Call<List<Comment>>
// https://jsonplaceholder.typicode.com/posts
@POST("posts")
fun createPost(@Body post : Post) : Call<Post>
// Please note you can Polymorphism too by using the same name of different methods but with different types of arguments.
@FormUrlEncoded
@POST("posts")
fun createPostWithField(@Field("userId") userId : Int , @Field("title") title : String , @Field("body") text : String) : Call<Post>
@FormUrlEncoded
@POST("posts")
fun createPostWithMap(@FieldMap fields : Map<String , String>) : Call<Post>
@Headers("Static-Header: 123")
@PUT("posts/{id}")
fun putPost(@Path("id") id : Int , @Body post : Post) : Call<Post>
@Headers("Static-Header: 123")
@PATCH("posts/{id}")
fun patchPost(@Path("id") id : Int , @Body post : Post) : Call<Post>
@DELETE("posts/{id}")
fun deletePost(@Path("id") id : Int) : Call<Post>
}
- Establish the connection and then create the request body.
private fun establishRetrofitConnection()
{
val gson : Gson = GsonBuilder().serializeNulls().create()
val loggingInterceptor = HttpLoggingInterceptor()
loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY)
val okHttpClient : OkHttpClient = OkHttpClient.Builder().addInterceptor(loggingInterceptor).build()
val retrofit : Retrofit = Retrofit.Builder().baseUrl("https://jsonplaceholder.typicode.com/").addConverterFactory(GsonConverterFactory.create(gson)).client(okHttpClient).build()
jsonPlaceholderAPI = retrofit.create(JSONPlaceholderAPI::class.java)
getPosts()
// getComments()
// getCommentsWithPostId()
// getSortedCommentsWithPostId()
// getSortedCommentsWithPostIds()
// getSortedCommentsWithParameters()
// getCommentsWithURL()
// createPost()
// createPostWithField()
// createPostWithMap()
// updatePost()
// deletePost()
}
private fun getPosts()
{
val call : Call<List<Post>> = jsonPlaceholderAPI.getPosts()
call.enqueue(object : Callback<List<Post>>
{
override fun onResponse(call : Call<List<Post>> , response : Response<List<Post>>)
{
println("MainActivity :: getPosts :: response : $response")
if (! response.isSuccessful)
{
txtResult.text = "Code: ${response.code()}"
return
}
val posts : List<Post> = response.body() !!
for (post in posts)
{
var context : String = ""
context += "ID: ${post.id}\n"
context += "USER_ID: ${post.userId}\n"
context += "TITLE: ${post.title}\n"
context += "TEXT: ${post.text}\n" + "\n"
txtResult.append(context)
}
}
override fun onFailure(call : Call<List<Post>> , t : Throwable)
{
txtResult.text = t.message
}
})
}
private fun getComments()
{
val call : Call<List<Comment>> = jsonPlaceholderAPI.getComments(3)
call.enqueue(object : Callback<List<Comment>>
{
override fun onResponse(call : Call<List<Comment>> , response : Response<List<Comment>>)
{
println("MainActivity :: getComments :: response : $response")
if (! response.isSuccessful)
{
txtResult.text = "Code: ${response.code()}"
return
}
val comments : List<Comment> = response.body() !!
for (comment in comments)
{
var context : String = ""
context += "ID: ${comment.id}\n"
context += "POST_ID: ${comment.postId}\n"
context += "NAME: ${comment.name}\n"
context += "EMAIL: ${comment.email}\n"
context += "COMMENT: ${comment.comment}\n" + "\n"
txtResult.append(context)
}
}
override fun onFailure(call : Call<List<Comment>> , t : Throwable)
{
txtResult.text = t.message
}
})
}
private fun getCommentsWithPostId()
{
val call : Call<List<Comment>> = jsonPlaceholderAPI.getCommentsWithPostId(10)
call.enqueue(object : Callback<List<Comment>>
{
override fun onResponse(call : Call<List<Comment>> , response : Response<List<Comment>>)
{
println("MainActivity :: getCommentsWithPostId :: response : $response")
if (! response.isSuccessful)
{
txtResult.text = "Code: ${response.code()}"
return
}
val comments : List<Comment> = response.body() !!
for (comment in comments)
{
var context : String = ""
context += "ID: ${comment.id}\n"
context += "POST_ID: ${comment.postId}\n"
context += "NAME: ${comment.name}\n"
context += "EMAIL: ${comment.email}\n"
context += "COMMENT: ${comment.comment}\n" + "\n"
txtResult.append(context)
}
}
override fun onFailure(call : Call<List<Comment>> , t : Throwable)
{
txtResult.text = t.message
}
})
}
private fun getSortedCommentsWithPostId()
{
val call : Call<List<Comment>> = jsonPlaceholderAPI.getSortedCommentsWithPostId(null , "id" , "null")
// You can pass null in these arguments to surpass the conditions
call.enqueue(object : Callback<List<Comment>>
{
override fun onResponse(call : Call<List<Comment>> , response : Response<List<Comment>>)
{
println("MainActivity :: getSortedCommentsWithPostId :: response : $response")
if (! response.isSuccessful)
{
txtResult.text = "Code: ${response.code()}"
return
}
val comments : List<Comment> = response.body() !!
for (comment in comments)
{
var context : String = ""
context += "ID: ${comment.id}\n"
context += "POST_ID: ${comment.postId}\n"
context += "NAME: ${comment.name}\n"
context += "EMAIL: ${comment.email}\n"
context += "COMMENT: ${comment.comment}\n" + "\n"
txtResult.append(context)
}
}
override fun onFailure(call : Call<List<Comment>> , t : Throwable)
{
txtResult.text = t.message
}
})
}
private fun getSortedCommentsWithPostIds()
{
val call : Call<List<Comment>> = jsonPlaceholderAPI.getSortedCommentsWithPostIds(listOf(1 , 3 , 5) , "id" , "null")
// You can pass null in these arguments to surpass the conditions
call.enqueue(object : Callback<List<Comment>>
{
override fun onResponse(call : Call<List<Comment>> , response : Response<List<Comment>>)
{
println("MainActivity :: getSortedCommentsWithPostIds :: response : $response")
if (! response.isSuccessful)
{
txtResult.text = "Code: ${response.code()}"
return
}
val comments : List<Comment> = response.body() !!
for (comment in comments)
{
var context : String = ""
context += "ID: ${comment.id}\n"
context += "POST_ID: ${comment.postId}\n"
context += "NAME: ${comment.name}\n"
context += "EMAIL: ${comment.email}\n"
context += "COMMENT: ${comment.comment}\n" + "\n"
txtResult.append(context)
}
}
override fun onFailure(call : Call<List<Comment>> , t : Throwable)
{
txtResult.text = t.message
}
})
}
private fun getSortedCommentsWithParameters()
{
val parameters = HashMap<String , String>().apply {
put("_order" , "asc")
put("_sort" , "id")
put("postId" , "1")
} as Map<String , String>
val call : Call<List<Comment>> = jsonPlaceholderAPI.getSortedCommentsWithParameters(parameters)
// You can pass null in these arguments to surpass the conditions
call.enqueue(object : Callback<List<Comment>>
{
override fun onResponse(call : Call<List<Comment>> , response : Response<List<Comment>>)
{
println("MainActivity :: getSortedCommentsWithPostIds :: response : $response")
if (! response.isSuccessful)
{
txtResult.text = "Code: ${response.code()}"
return
}
val comments : List<Comment> = response.body() !!
for (comment in comments)
{
var context : String = ""
context += "ID: ${comment.id}\n"
context += "POST_ID: ${comment.postId}\n"
context += "NAME: ${comment.name}\n"
context += "EMAIL: ${comment.email}\n"
context += "COMMENT: ${comment.comment}\n" + "\n"
txtResult.append(context)
}
}
override fun onFailure(call : Call<List<Comment>> , t : Throwable)
{
txtResult.text = t.message
}
})
}
private fun getCommentsWithURL()
{
val call : Call<List<Comment>> = jsonPlaceholderAPI.getCommentsWithURL("posts/1/comments")
// You can pass null in these arguments to surpass the conditions
call.enqueue(object : Callback<List<Comment>>
{
override fun onResponse(call : Call<List<Comment>> , response : Response<List<Comment>>)
{
println("MainActivity :: getCommentsWithURL :: response : $response")
if (! response.isSuccessful)
{
txtResult.text = "Code: ${response.code()}"
return
}
val comments : List<Comment> = response.body() !!
for (comment in comments)
{
var context : String = ""
context += "ID: ${comment.id}\n"
context += "POST_ID: ${comment.postId}\n"
context += "NAME: ${comment.name}\n"
context += "EMAIL: ${comment.email}\n"
context += "COMMENT: ${comment.comment}\n" + "\n"
txtResult.append(context)
}
}
override fun onFailure(call : Call<List<Comment>> , t : Throwable)
{
txtResult.text = t.message
}
})
}
private fun createPost()
{
val post = Post(12341 , "Learn Retrofit" , "Learning Retrofit and Kotlin at the same time")
val call : Call<Post> = jsonPlaceholderAPI.createPost(post)
call.enqueue(object : Callback<Post>
{
override fun onResponse(call : Call<Post> , response : Response<Post>)
{
println("MainActivity :: createPost :: response : $response")
if (! response.isSuccessful)
{
txtResult.text = "Code ${response.code()}"
return
}
val postResponse : Post? = response.body()
var context = ""
context += "ID: ${postResponse !!.id}\n"
context += "USER_ID: ${postResponse.userId}\n"
context += "TITLE: ${postResponse.title}\n"
context += "TEXT: ${postResponse.text}\n" + "\n"
txtResult.append(context)
}
override fun onFailure(call : Call<Post> , t : Throwable)
{
txtResult.text = t.message
}
})
}
private fun createPostWithField()
{
val call : Call<Post> = jsonPlaceholderAPI.createPostWithField(12342 , "Learn Retrofit Post" , "Learning uses of @FormURLEncoded and @Field")
call.enqueue(object : Callback<Post>
{
override fun onResponse(call : Call<Post> , response : Response<Post>)
{
println("MainActivity :: createPostWithField :: response : $response")
if (! response.isSuccessful)
{
txtResult.text = "Code ${response.code()}"
return
}
val postResponse : Post? = response.body()
var context = ""
context += "ID: ${postResponse !!.id}\n"
context += "USER_ID: ${postResponse.userId}\n"
context += "TITLE: ${postResponse.title}\n"
context += "TEXT: ${postResponse.text}\n" + "\n"
txtResult.append(context)
}
override fun onFailure(call : Call<Post> , t : Throwable)
{
txtResult.text = t.message
}
})
}
private fun createPostWithMap()
{
val inputFields = HashMap<String , String>().apply {
put("userId" , "12343")
put("title" , "Learning Retrofit Post")
put("body" , "Learning @FieldMap, HashMap, Map and casting of Hashmap to Map")
} as Map<String , String>
val call : Call<Post> = jsonPlaceholderAPI.createPostWithMap(inputFields)
call.enqueue(object : Callback<Post>
{
override fun onResponse(call : Call<Post> , response : Response<Post>)
{
println("MainActivity :: createPostWithMap :: response : $response")
if (! response.isSuccessful)
{
txtResult.text = "Code : ${response.code()}"
return
}
val postResponse : Post? = response.body()
var context = ""
context += "ID: ${postResponse !!.id}\n"
context += "USER_ID: ${postResponse.userId}\n"
context += "TITLE: ${postResponse.title}\n"
context += "BODY: ${postResponse.text}\n" + "\n"
txtResult.append(context)
}
override fun onFailure(call : Call<Post> , t : Throwable)
{
txtResult.text = t.message
}
})
}
private fun updatePost()
{
val post = Post(6 , "Learning Retrofit Put" , "Learning @PUT annotation with @PATH and @BODY annotation")
val call : Call<Post> = jsonPlaceholderAPI.putPost(5 , post)
call.enqueue(object : Callback<Post>
{
override fun onResponse(call : Call<Post> , response : Response<Post>)
{
println("MainActivity :: putPost :: response : $response")
if (! response.isSuccessful)
{
txtResult.text = "Code : ${response.code()}"
return
}
else
{
val putResponse : Post? = response.body()
var context = ""
context += "ID: ${putResponse !!.id}\n"
context += "USER_ID: ${putResponse.userId}\n"
context += "TITLE: ${putResponse.title}\n"
context += "BODY: ${putResponse.text}\n" + "\n"
txtResult.append(context)
}
}
override fun onFailure(call : Call<Post> , t : Throwable)
{
txtResult.text = t.message
}
})
}
private fun deletePost()
{
val call : Call<Post> = jsonPlaceholderAPI.deletePost(5)
call.enqueue(object : Callback<Post>
{
override fun onResponse(call : Call<Post> , response : Response<Post>)
{
println("MainActivity :: deletePost :: response : $response")
txtResult.text = "Code : ${response.code()}"
}
override fun onFailure(call : Call<Post> , t : Throwable)
{
txtResult.text = t.message
}
})
}
Comments
Post a Comment