Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Gson 2.8,.6 fails to serialize/deserialize SparseArray on Android 10 #1660

Closed
bamibestelt opened this issue Mar 1, 2020 · 3 comments
Closed

Comments

@bamibestelt
Copy link

I'm using Gson in my @TypeConverter class to convert SparseArray objects into json String to be saved in Room database. Here is how I do it:

`class RoomTypeConverter {

@TypeConverter
fun sparseArrayToString(sparseArray: SparseArray<String>) : String = Gson().toJson(sparseArray)

@TypeConverter
fun stringToSparseArray(string: String) : SparseArray<String> = Gson().fromJson(string, object: TypeToken<SparseArray<String>>() {}.type)

@TypeConverter
fun sparseIntArrayToString(sparseIntArray: SparseIntArray) : String = Gson().toJson(sparseIntArray)

@TypeConverter
fun stringToSparseIntArray(string: String) : SparseIntArray = Gson().fromJson(string, SparseIntArray::class.java)

}`

The TypeConverter works fine for Android 9 and below as SparseArray successfully converted as JSON string, but fails to work properly on Android 10 as the JSON string saved in database are just empty JSON "{}".

@lyubomyr-shaydariv
Copy link
Contributor

You should not (de)serialize objects of classes you don't control and don't know it's structure. What you should do: convert your sparse array to a DTO object that is Gson-friendly (simple built-ins like List, Map). Why: Gson does not support the Android runtime classes directly, and mostly picks up a type adapter that (de)serializes the object field-by-field including its private fields that are not excluded (neither transient, nor excluded explicitly). You probably need to implement a custom type adapter too for the reasons of backwards compatibility. See more: #1573 #1613

@ozmium
Copy link

ozmium commented Jun 2, 2021

The exact same problem happens with Json-IO: It works fine on Android 9 and below, but on Android 10/11, Json-IO will save a SparseArray as an empty {"@type":"android.util.SparseArray"} with no object mappings.

The solution/workaround is to use HashMap<Long, Object> instead of SparseArray<Object>. This will work on all Android versions from Android 4 to Android 11, with correct serialization and deserialization. And HashMap has a similar interface to SparseArray.

Note that HashMap<Integer, Object> does not work with Json-IO on Android 10/11 (see jdereg/json-io#141), but it may work with Gson.

@Marcono1234
Copy link
Collaborator

Closing this issue because as mentioned in #1660 (comment) you should not rely on reflection-based serialization for third-party classes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants