Преобразование строки json Intent в объект Intent, предоставляющий исключение

Я использую класс Gson для преобразования строковых данных JSON в объект Intent. Но я получаю исключение.

Строка JSON цели:

{
 "targetIntent":{
 "mAction":"android.intent.action.VIEW",
 "mData":{
 "authority":{
 "decoded":"com.android.contacts",
 "encoded":"com.android.contacts"
 },
 "fragment":{
 },
 "path":{
 "decoded":"NOT CACHED",
 "encoded":"/contacts/lookup/1471i541ce89b89ad6a59"
 },
 "query":{
 },
 "scheme":"content",
 "uriString":"NOT CACHED",
 "host":"NOT CACHED",
 "port":-2
 },
 "mFlags":0
 }
}

Код конверсии:

Intent targetIntent =
 gson.fromJson(histroyDataObject.getString("targetIntent"), Intent.class);

Это дает исключение:

Cause: Instantiation Exception
Detail Message: Failed to invoke private android.net.Uri() with no args

Трассировка стека:

08-31 01:08:19.045: W/System.err(290): Caused by: java.lang.InstantiationException: android.net.Uri
08-31 01:08:19.065: W/System.err(290): at java.lang.reflect.Constructor.constructNative(Native Method)
08-31 01:08:19.065: W/System.err(290): at java.lang.reflect.Constructor.newInstance(Constructor.java:446)
08-31 01:08:19.065: W/System.err(290): at com.google.gson.internal.ConstructorConstructor$2.construct(ConstructorConstructor.java:91)
08-31 01:08:19.076: W/System.err(290): ... 24 more

Спасибо за вашу помощь.

2 ответа

Моя ставка Intent#uriString имеет тип android.net.Uri, у которого нет конструктора public no-arg. Я имею в виду, что вы должны написать JsonDeserializer следующим образом:

public class UriDeserializer implements JsonDeserializer<uri> {
 @Override
 public Uri deserialize(final JsonElement src, final Type srcType,
 final JsonDeserializationContext context) throws JsonParseException {
 return Uri.parse(src.getAsString());
 }
}
</uri>

а затем зарегистрируйте его через GsonBuilder:

Gson gson = new GsonBuilder()
 .registerTypeAdapter(Uri.class, new UriDeserializer())
 .create();

EDIT:

Вам необходимо зарегистрировать настраиваемые адаптеры, если какое-либо свойство не определяет открытый конструктор no-arg. Вы можете прочитать больше в Gson docs - Пользовательская сериализация и десериализация.


Я не знаком с разработкой Android, но смотрю на исходный код android.net.Uri class http://grepcode.com/file_/repository.grepcode.com/java/ext/com.google.android/android/2.1_r2/android/net/Uri.java/?v=source Я вижу, что это абстрактный класс. Так что это, вероятно, главная причина, почему он терпит неудачу. Чтобы заставить его работать, вам нужно написать собственный TypeAdapter и использовать метод parse для класса URI для Android.

Вы также можете посмотреть библиотеку Genson http://code.google.com/p/genson/. Он имеет приятные функции и выступления. Кроме того, он весит столько же, сколько gson (200K). Пример с Genson для вашей проблемы:

class AndroidURIDeserializer implements Deserializer<uri> {
 public Uri deserialize(ObjectReader reader, Context ctx) throws TransformationException,
 IOException {
 return Uri.parse(reader.valueAsString());
 }
}
Genson genson = new Genson.Builder().withDeserializers(new AndroidURIDeserializer()).create();
Intent pojo = genson.deserialize(json, Intent.class);
</uri>

licensed under cc by-sa 3.0 with attribution.