我正在尝试为我在 Android Studio Java 中制作的自定义对象编写一个简单的对象类型转换器。我的对象称为 MapAnnotationObject,并包含三个由以下对象组成的 ArrayList:Markers、Circles 和 PolyLines,所有这些都是 GoogleMaps 实例上的可绘制对象:
import com.google.android.gms.maps.model.Circle;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import java.io.Serializable;
import java.util.ArrayList;
public class MapAnnotationObject implements Serializable {
ArrayList<Marker> markerList;
ArrayList<Circle> circleList;
ArrayList<ArrayList<LatLng>> polyLineList;
public MapAnnotationObject(){
markerList = new ArrayList<>();
circleList = new ArrayList<>();
polyLineList = new ArrayList<>();
}
public void addToMarkerList(Marker marker){markerList.add(marker);}
public void addToCircleList(Circle circle){circleList.add(circle);}
public void addToPolyLineList(ArrayList<LatLng> coords){polyLineList.add(coords);}
public ArrayList<Marker> getMarkerList(){return markerList;}
public ArrayList<Circle> getCircleList(){return circleList;}
public ArrayList<ArrayList<LatLng>> getPolyLineList(){return polyLineList;}
public void removeFromMarkerList(Marker marker){markerList.remove(marker);}
public Circle removeFromCircleList(Circle circle){
circleList.remove(circle);
return circle;
}
}
我想将此对象存储在 Room 数据库中,为此我利用 Gson 编写了一个对象转换器:
import androidx.room.TypeConverter;
import androidx.room.TypeConverters;
import com.example.coursework_2.objects.GeofenceObject;
import com.example.coursework_2.objects.MapAnnotationObject;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import java.lang.reflect.Type;
public class MapAnnotationObjectConverter {
static Gson gson = new Gson();
@TypeConverter
public static MapAnnotationObject stringToMapAnnotationObject(String data){
if (data == null){
return new MapAnnotationObject();
}
Type mapObjectType = new TypeToken<MapAnnotationObject>() {}.getType();
return gson.fromJson(data, mapObjectType);
}
@TypeConverter
public static String mapAnnotationObjectToString(MapAnnotationObject mapAnnotationObject){
return gson.toJson(mapAnnotationObject);
}
}
数据库中以下列来存储对象:
@ColumnInfo(name = "map_annotations")
@TypeConverters(MapAnnotationObjectConverter.class)
public MapAnnotationObject map_annotations;
但是,每当我尝试添加到 Room 数据库时,都会收到以下错误:
java.lang.AssertionError: AssertionError (GSON 2.8.5): java.lang.NoSuchFieldException: ALL_OBJECT_POOL
Logcat 识别出出现在我的类型转换器中的这一行:
return gson.toJson(mapAnnotationObject);
我真的不知道是什么导致了问题以及如何解决它,任何帮助或指导将不胜感激!
我有第二个自定义对象被实现到数据库中,它使用完全相同的代码,没有任何问题,所以我研究了可能找到一种方法来单独转换所有 ArrayList,但我不确定这是否是正确的过程是否采取行动。
您遇到的问题可能与 Gson 库尝试序列化 MapAnnotationObject 并由于对象的内部结构(包含 ArrayList 和其他复杂结构)而面临困难有关。
一种解决方案是为 Gson 编写自定义 TypeAdapter 来处理 MapAnnotationObject 的序列化和反序列化。以下是如何为 MapAnnotationObject 实现自定义 TypeAdapter 的示例:
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;
import java.io.IOException;
import java.lang.reflect.Type;
import java.util.ArrayList;
public class MapAnnotationObjectTypeAdapter extends TypeAdapter<MapAnnotationObject> {
@Override
public void write(JsonWriter out, MapAnnotationObject value) throws IOException {
out.beginObject();
out.name("markerList");
writeList(out, value.getMarkerList());
out.name("circleList");
writeList(out, value.getCircleList());
out.name("polyLineList");
writeNestedList(out, value.getPolyLineList());
out.endObject();
}
@Override
public MapAnnotationObject read(JsonReader in) throws IOException {
MapAnnotationObject mapAnnotationObject = new MapAnnotationObject();
in.beginObject();
while (in.hasNext()) {
String name = in.nextName();
switch (name) {
case "markerList":
mapAnnotationObject.setMarkerList(readList(in, Marker.class));
break;
case "circleList":
mapAnnotationObject.setCircleList(readList(in, Circle.class));
break;
case "polyLineList":
mapAnnotationObject.setPolyLineList(readNestedList(in, LatLng.class));
break;
default:
in.skipValue();
}
}
in.endObject();
return mapAnnotationObject;
}
private <T> void writeList(JsonWriter out, ArrayList<T> list) throws IOException {
out.beginArray();
for (T item : list) {
gson.toJson(item, item.getClass(), out);
}
out.endArray();
}
private <T> ArrayList<T> readList(JsonReader in, Class<T> type) throws IOException {
ArrayList<T> list = new ArrayList<>();
in.beginArray();
while (in.hasNext()) {
list.add(gson.fromJson(in, type));
}
in.endArray();
return list;
}
private <T> void writeNestedList(JsonWriter out, ArrayList<ArrayList<T>> nestedList) throws IOException {
out.beginArray();
for (ArrayList<T> list : nestedList) {
writeList(out, list);
}
out.endArray();
}
private <T> ArrayList<ArrayList<T>> readNestedList(JsonReader in, Class<T> type) throws IOException {
ArrayList<ArrayList<T>> nestedList = new ArrayList<>();
in.beginArray();
while (in.hasNext()) {
nestedList.add(readList(in, type));
}
in.endArray();
return nestedList;
}
}
public class MapAnnotationObjectConverter {
static Gson gson = new GsonBuilder()
.registerTypeAdapter(MapAnnotationObject.class, new MapAnnotationObjectTypeAdapter())
.create();
@TypeConverter
public static MapAnnotationObject stringToMapAnnotationObject(String data){
if (data == null){
return new MapAnnotationObject();
}
Type mapObjectType = new TypeToken<MapAnnotationObject>() {}.getType();
return gson.fromJson(data, mapObjectType);
}
@TypeConverter
public static String mapAnnotationObjectToString(MapAnnotationObject mapAnnotationObject){
return gson.toJson(mapAnnotationObject);
}
}
这样,您就可以显式定义 Gson 如何序列化和反序列化您的复杂对象,并处理 ArrayList 及其内容。这可能会解决您面临的 NoSuchFieldException 问题。