Retrofit Jackson
In this tutorial you will learn how to download data via Retrofit and parse it using the Jackson Kotlin module.
What is Jackson?
Jackson is a always tagged as "the Java JSON library" or simply as "JSON for Java".
It is a suite of data-processing tools for Java (and the JVM platform), including the flagship streaming JSON parser / generator library, matching data-binding library (POJOs to and from JSON) and additional data format modules to process data encoded in Avro, BSON, CBOR, CSV, Smile, Java Properties, Protobuf, TOML, XML or YAML; and even the large set of data format modules to support data types of widely used data types such as Guava, Joda, PCollectionsnand many, many more .
Read more the Jackson Project FAQ.
Example 1: Kotlin Android Retrofit Jackson Example
Here is a simple example. Here is the image screenshot:
Step 1: Create Project
Start by creating an empty Android Studio
project.
Step 2: Dependencies
Here are the dependencies you will need:
implementation "com.squareup.retrofit2:retrofit:$retrofitVersion"
implementation "androidx.recyclerview:recyclerview:$supportVer"
implementation "androidx.cardview:cardview:$supportVer"
implementation "com.squareup.picasso:picasso:$picassoVersion"
implementation "com.squareup.retrofit2:converter-jackson:$retrofitJacksonConverter"
}
Included are the Retrofit, which is teh HTTP client, RecyclerView for rendering data, Picasso for downloading images and converter-jackson
for deserializing JSON into Kotlin data classes.
Step : Create Model classes
MovieResult.kt
import com.fasterxml.jackson.annotation.JsonProperty
data class MovieResult(
@JsonProperty("page") var page: Int = 0, //1
@JsonProperty("total_results") var totalResults: Int = 0, //19788
@JsonProperty("total_pages") var totalPages: Int = 0, //990
@JsonProperty("results") var results: List<Result> = listOf()
)
data class Result(
@JsonProperty("vote_count") var voteCount: Int = 0, //6793
@JsonProperty("id") var id: Int = 0, //198663
@JsonProperty("video") var video: Boolean = false, //false
@JsonProperty("vote_average") var voteAverage: Int = 0, //7
@JsonProperty("title") var title: String = "", //The Maze Runner
@JsonProperty("popularity") var popularity: Double = 0.0, //535.445142
@JsonProperty("poster_path") var posterPath: String = "", ///coss7RgL0NH6g4fC2s5atvf3dFO.jpg
@JsonProperty("original_language") var originalLanguage: String = "", //en
@JsonProperty("original_title") var originalTitle: String = "", //The Maze Runner
@JsonProperty("genre_ids") var genreIds: List<Int> = listOf(),
@JsonProperty("backdrop_path") var backdropPath: String = "", ///lkOZcsXcOLZYeJ2YxJd3vSldvU4.jpg
@JsonProperty("adult") var adult: Boolean = false, //false
@JsonProperty("overview") var overview: String = "", //Set in a post-apocalyptic world, young Thomas is deposited in a community of boys after his memory is erased, soon learning they're all trapped in a maze that will require him to join forces with fellow “runners” for a shot at escape.
@JsonProperty("release_date") var releaseDate: String = "" //2014-09-10
)
Step : Create API Interface
ApiInterface.kt
import com.developers.jacksonkotlinmodule.model.MovieResult
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
import retrofit2.Call
import retrofit2.Retrofit
import retrofit2.converter.jackson.JacksonConverterFactory
import retrofit2.http.GET
import retrofit2.http.Query
interface ApiInterface {
@GET("popular")
fun getMovies(@Query("api_key") key: String,
@Query("page") page: Int): Call<MovieResult>
companion object Factory {
fun create(): ApiInterface {
val retrofit = Retrofit.Builder()
.addConverterFactory(JacksonConverterFactory.create(
jacksonObjectMapper()
))
.baseUrl("https://api.themoviedb.org/3/movie/")
.build()
return retrofit.create(ApiInterface::class.java);
}
}
}
Step : Create Adapter
MovieAdapter.kt
import android.net.Uri
import androidx.recyclerview.widget.RecyclerView
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.developers.jacksonkotlinmodule.R
import com.developers.jacksonkotlinmodule.model.Result
import com.squareup.picasso.Callback
import com.squareup.picasso.Picasso
import kotlinx.android.synthetic.main.list_row.view.*
import android.content.Context
class MovieAdapter(private val context: Context, private val resultList: List<Result>?)
: RecyclerView.Adapter<MovieAdapter.MyViewHolder>() {
override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
holder?.bindItems(resultList?.get(position))
}
override fun getItemCount(): Int {
return resultList?.size!!
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
val view = LayoutInflater.from(context).inflate(R.layout.list_row, parent,
false)
return MyViewHolder(view)
}
class MyViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
fun bindItems(result: Result?) {
itemView.movie_title.text = result?.title
val posterUri = Uri.parse("http://image.tmdb.org/t/p/w185/").buildUpon()
.appendEncodedPath(result?.posterPath)
.build()
itemView.progress_bar.visibility = View.VISIBLE
Picasso.with(itemView.context).load(posterUri.toString())
.into(itemView.image_view_movie, object : Callback {
override fun onError() {
//Show Error here
}
override fun onSuccess() {
itemView.progress_bar.visibility = View.GONE
}
})
}
}
}
Step : Fetch and Render Movies
MainActivity.kt
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.recyclerview.widget.GridLayoutManager
import com.developers.jacksonkotlinmodule.adapter.MovieAdapter
import com.developers.jacksonkotlinmodule.model.MovieResult
import kotlinx.android.synthetic.main.activity_main.*
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import java.util.logging.Logger
class MainActivity : AppCompatActivity() {
companion object {
val Log = Logger.getLogger(MainActivity::class.java.name)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val apiCall = ApiInterface.create()
apiCall.getMovies(BuildConfig.MOVIE_KEY, 1)
.enqueue(object : Callback<MovieResult> {
override fun onResponse(call: Call<MovieResult>?, response: Response<MovieResult>?) {
Log.info(response?.body()?.results!![0].posterPath + " ")
val movieResponse = response.body()
val resultList = movieResponse?.results
val layoutManager = GridLayoutManager(applicationContext, 2)
val adapter = MovieAdapter(applicationContext, resultList)
movie_recycler_view.layoutManager = layoutManager
movie_recycler_view.adapter = adapter
}
override fun onFailure(call: Call<MovieResult>?, t: Throwable?) {
t?.printStackTrace()
}
})
}
}
Run
Copy the code or download it in the link below, build and run.
Reference
Here are the reference links:
Number | Link |
---|---|
1. | Download Example |
2. | Follow code author |
3. | Code: Apache 2.0 License |