Undervejs i udviklingen af min app har jeg brugt nogle forskellige eksterne pakker til at tage vare på forskellige opgaver. Her vil jeg kort beskrive Gson, som bruges til at håndtere json, det vil sige konverte json til modelklasser og omvendt.

Gson opsætning / gradle

I din build.gradle (module:app) skal linjen “implementation ‘com.google.code.gson:gson:2.8.5’” indsættes under dependencies:

dependencies {
  ...
  implementation 'com.google.code.gson:gson:2.8.5'
  ...
}

Husk at sync’e efter du har lavet ændringer i en eller flere gradle-filer.

Fra Json til model

Følgende data class/modelklasse “Request” bruges i eksemplerne i afsnittene nedenfor:

data class Request( var id: Int,
                    var textToTranslate: String,
                    var languageOrigin: String,
                    var languageTarget: String)

For at omdanne en json streng til ovenstående klasse gøres følgende:

val jsonString = "{ \"id\": 1, \"textToTranslate\": \"Das blaue Pferd\", \"languageOrigin\": \"Tysk\", \"languageTarget\": \"Dansk\" }"
val gson = Gson()
val topic = gson.fromJson(jsonString, Request::class.java)

Da Gson er lavet til java, skal man bruge en java class reference - det er derfor Request klassen er angivet på denne måde: Request::class.java.

Havde man bare skrevet Request::class ville det være en kotlin class reference, og den kan Gson ikke finde ud af at bruge.

Fra Json array til liste af model

Følgende json streng skal deserializes, og ligger i variablen jsonString:

[
    {
      "id": 1,
      "textToTranslate": "Das blaue Pferd",
      "languageOrigin": "Tysk",
      "languageTarget": "Dansk"
    },
    {
      "id": 2,
      "textToTranslate": "Yksi kaksi kolme",
      "languageOrigin": "Finsk",
      "languageTarget": "Dansk"
    },
    {
      "id": 3,
      "textToTranslate": "Portez ce vieux whisky au juge blond qui fume",
      "languageOrigin": "Fransk",
      "languageTarget": "Dansk"
    }
  ]

I Kotlin bruges følgende kode:

  val jsonString = ".../* se ovenstående json */..."
  val gson = Gson()
  var realRequests = mutableListOf<Request>()
  val collectionType = object : TypeToken<MutableList<Request>>() { }.type
  realRequests = gson.fromJson(jsonString, collectionType)

De to sidste linjer er i virkeligheden der hvor det sjove sker:

  • val listType = object : ... definerer den type collection som jeg vil deserialize min jsonString til.
  • gson.fromJson(jsonString, collectionType) gør præcis det samme som i forrige afsnit, men nu med den type collection som vi definerede i linjen over.

Eksemplet er naturligvis tilpasset til kotlin, men selv i dokumentatione til Gson, som bruger java til sine eksempler, står der:

Fairly hideous: note how we define the type of collection. Unfortunately, there is no way to get around this in Java.

Model til Json

Det er nemt at komme fra model til json:

  val model = Request(1, "Stay in school", "Engelsk", "Dansk")
  val gson = Gson()
  val json: String = gson.toJson(model)

ovenstående producerer følgende json streng:

{
  "id": 1,
  "textToTranslate": "Stay in school",
  "languageOrigin": "Engelsk",
  "languageTarget": "Dansk"  
}

Reflektion over Gson

Gson er rimelig nemt at bruge, men det var besværligt at komme igang med, da det i udgangspunktet er skrevet til brug med java. Det krævede mange søgninger for at finde gode eksempler på brugen af Gson sammen med Kotlin, men når man først kommer igang går det rimelig nemt. Og syntaksen er også rimelig overskuelig.

En af de ting der voldte flest problemer var at omdanne json arrays til collections af min modelklasse, men det kunne også løses ved hjælp af søgning.

Jeg har haft kigget efter flere muligheder for at omdanne json i min app, men det har været besværligt at finde nogle gode pakker jeg kunne bruge. Jeg undersøgte også kotlins egne Json biblioteker, men gik bort fram dem igen, da de fleste blogs og andre kilder på nettet aldrig nævnte dem og oftest nævnt netop Gson.

Her viser jeg kun meget grundlæggende hvordan Gson kan bruges mest simpelt, men der er naturligvis flere muligheder for tilpasning.

Yderligere ressourcer