I’ve been working on server side programming for almost two years now. I’ve had a bunch of ideas for apps to create, but they require me to learn something on the “front end”. Since I don’t want to worry much about security, keeping the server up and running, and similar problems on the server, I’ve decided to start making Android apps for myself, and maybe publishing them, and even keeping some of them open source on GitHub.
I’ve started working on a simple CRUD app, when I got to a problem that I need to pass objects, specifically a list of objects, to a new activity. It was ugly to serialize/deserialize, or even use Parcelable. I’ve decided to use JSON to pass objects through activities, since my data classes don’t have to implement anything.
I’ve started programming on Android with Kotlin right away, and it’s amazing what you can do and how natural it feels. The following is what I’ve done to make passing objects to new activities as naturally as possible.
Add GSON dependency to build.gradle
:
implementation 'com.google.code.gson:gson:2.8.5'
Make a file IntentUtil.kt
and inside put:
import android.content.Intent
import com.google.gson.Gson
import com.google.gson.GsonBuilder
const val DEFAULT_NAME = "object"
object IntentUtil {
@Suppress("SpellCheckingInspection")
val gson: Gson = GsonBuilder().create()
}
fun Intent.putExtraJson(name: String, src: Any) {
putExtra(name, IntentUtil.gson.toJson(src))
}
fun Intent.putExtraJson(src: Any) {
putExtra(DEFAULT_NAME, IntentUtil.gson.toJson(src))
}
fun <T> Intent.getJsonExtra(name: String, `class`: Class<T>): T? {
val stringExtra = getStringExtra(name)
if (stringExtra != null) {
return IntentUtil.gson.fromJson<T>(stringExtra, `class`)
}
return null
}
fun <T> Intent.getJsonExtra(`class`: Class<T>): T? {
val stringExtra = getStringExtra(DEFAULT_NAME)
if (stringExtra != null) {
return IntentUtil.gson.fromJson<T>(stringExtra, `class`)
}
return null
}
There are two “overloaded” functions, putExtraJson
and getJsonExtra
. The functions are actually extension functions,
so they can be called on an instance of Intent
class.
I’ll use some basic class just for the example:
data class MySimpleClass(val title: String, val note: String?)
Now, making new activity:
val intent = Intent(this, MySimpleActivity::class.java)
intent.putExtraJson(new MySimpleClass("Hello world","Note"))
startActivity(intent)
This will put a JSON string with default name “object” to intents extra. Getting an instance of a class is just as simple:
val mySimpleClass: MySimpleClass? = intent.getJsonExtra(MySimpleClass::class.java)
The reason this returns a nullable instance is that sometimes we need to check the new activity if we got an object passed by, and show different things if they are passed or not.
You can also pass a custom name, which is the overloaded version of the function:
intent.putExtraJson("mySimpleClass", new MySimpleClass("Hello world","Note"))
And then get the object by calling:
val mySimpleClass = intent.getJonExtra("mySimpleClass", MySimpleClass::class.java)
I haven’t done any particular benchmarks or testing for this, but it works for my case.
I’ll keep the post updated if I run into problems with this.