Use Moshi as Android Json Library (Kotlin)

Jan 22, 2019
Include Retrofit integration

Why use Moshi?

NOTE: Faster than Gson, more lightweight than Jackson, "modern", uses Okio library for optimization (used by OkHttp and Retrofit as well).

Dependencies

// https://mvnrepository.com/artifact/com.squareup.moshi/moshi-kotlin
def moshi_version = '1.8.0'

implementation "com.squareup.moshi:moshi-kotlin:$moshi_version"

// Optional: generate small and fast adapter for each of your Kotlin classes 
kapt "com.squareup.moshi:moshi-kotlin-codegen:$moshi_version"

Proguard

Refer to Moshi R8 / ProGuard

Usage

Create Moshi object.

val moshi = Moshi.Builder()      .add(KotlinJsonAdapterFactory())      .add(LocalDateTimeAdapter())      .add(MultipleFormatsDateAdapter())      .build()

NOTE: Refer to Moshi DateTime Adapter With Multiple Format Support for LocalDateTimeAdapter and MultipleFormatsDateAdapter().

Create Moshi adapter to parse Json to object and vice versa.

var jsonString = "..."// create adapterval adapter = moshi.adapter<RateAppReminder>(RateAppReminder::class.java)val item = adapter.fromJson(jsonString)jsonString = adapter.toJson(item)

Json Class

@JsonClass(generateAdapter = true)class RateAppReminder {    class Reminder(val date: LocalDateTime, val sessionCount: Long)    @Json(name = "last_reminder")    var lastReminder: Reminder? = null    @Json(name = "reminder_count")    var reminderCount: Int = 0    // isRated    @Json(name = "is_done")    var isDone: Boolean = false}

NOTE: @JsonClass is optional, but do use it with moshi-kotlin-codegen for faster adapter generation.

NOTE: @Json is optional, but I like things to be more verbose and perfer snake_case as opposed to camelCase for json.

Integration with Retrofit

fun provideApiService(moshi: Moshi): ApiService {    val okHttpClientBuilder = OkHttpClient.Builder()            .readTimeout(30, TimeUnit.SECONDS)            .writeTimeout(30, TimeUnit.SECONDS)    if (BuildConfig.DEBUG) {        val logging = HttpLoggingInterceptor()        logging.level = HttpLoggingInterceptor.Level.BODY        okHttpClientBuilder.addInterceptor(logging)    }    val retrofit = Retrofit.Builder()            .baseUrl("https://api.mydomain.com")            .addConverterFactory(MoshiConverterFactory.create(moshi))            // .addCallAdapterFactory(CoroutineCallAdapterFactory())            .client(okHttpClientBuilder.build())            .build()    return retrofit.create(ApiService::class.java)}

❤️ Is this article helpful?

Buy me a coffee ☕ or support my work via PayPal to keep this space 🖖 and ad-free.

Do send some 💖 to @d_luaz or share this article.

✨ By Desmond Lua

A dream boy who enjoys making apps, travelling and making youtube videos. Follow me on @d_luaz

👶 Apps I built

Travelopy - discover travel places in Malaysia, Singapore, Taiwan, Japan.