After updating the targetSdk to 31, gson.ToJson started giving empty results for List<File> on android 12 device (vivo v2036). Tried passing TypeToken as well still remains the same. Funny thing is that its working fine on lower androids and on targetSdk 30.
public void save(Context context, List<File> files) {
Gson gson = new Gson();
String json = gson.toJson(files);
//getting json value as "[{}]"
}
Gson has no built-in adapter for
java.io.Fileso it falls back to using reflection. This should be avoided for third-party classes because it accesses their internal fields which makes you dependent on their internal implementation. That internal implementation could change at any point because it is not part of the public API, and can therefore break your JSON serialization logic.As mentioned by @CommonsWare you can either change the type of the list to
List<String>and by doing so only use types for which Gson has built-in adapters. Or you can also solve this by registering a customTypeAdapterforFile:(Coincidentally this custom
TypeAdapteralso produces more compact JSON because it serializes theFileas a JSON string value whereas the reflection-based adapter would serialize it as JSON object with JSON string property.)You can then register the adapter like this:
If that does not solve your issue, you could also try registering the adapter with
GsonBuilder.registerTypeHierarchyAdapter. Possibly Android is creating instances of customFilesubclasses.To detect any cases where you accidentally depend on reflection-based serialization for Android classes you can use
GsonBuilder.addReflectionAccessFilter(ReflectionAccessFilter.BLOCK_ALL_ANDROID)(requires Gson 2.9.1 or newer).