Android Studio自定义对象类型转换报错NoSuchFieldException: ALL_OBJECT_POOL
问题原因与解决方案
核心问题
你遇到的NoSuchFieldException: ALL_OBJECT_POOL错误,本质是Google Maps的Marker、Circle、PolyLine并非可序列化的数据模型类,而是地图SDK中的视图层对象——它们内部包含大量私有隐藏字段(比如ALL_OBJECT_POOL)、上下文引用或未开放的内部逻辑,Gson在尝试反射序列化这些对象时,无法访问这些私有字段,从而抛出断言错误。
另一个自定义对象能正常工作,是因为它是纯POJO(普通Java对象),没有引用这类系统级的非序列化对象。
正确解决思路
不能直接存储Marker/Circle/PolyLine对象,必须将它们转换为自定义的可序列化数据模型类,只存储重建这些地图元素所需的关键数据,而不是对象本身。
步骤1:创建对应的数据模型类
针对每种地图元素,提取需要保存的核心属性,比如:
Marker数据模型
public class MarkerData { private double lat; private double lng; private String title; private String snippet; // 从Marker对象初始化数据模型 public MarkerData(Marker marker) { this.lat = marker.getPosition().latitude; this.lng = marker.getPosition().longitude; this.title = marker.getTitle(); this.snippet = marker.getSnippet(); // 若需要保存图标,可存储图标资源ID或远程URL,而非Drawable对象 } // 从数据模型重建Marker public MarkerOptions toMarkerOptions() { return new MarkerOptions() .position(new LatLng(lat, lng)) .title(title) .snippet(snippet); } // 空构造方法(Gson序列化需要)、getter/setter public MarkerData() {} }
Circle数据模型
public class CircleData { private double centerLat; private double centerLng; private double radius; private int fillColor; private int strokeColor; public CircleData(Circle circle) { this.centerLat = circle.getCenter().latitude; this.centerLng = circle.getCenter().longitude; this.radius = circle.getRadius(); this.fillColor = circle.getFillColor(); this.strokeColor = circle.getStrokeColor(); } public CircleOptions toCircleOptions() { return new CircleOptions() .center(new LatLng(centerLat, centerLng)) .radius(radius) .fillColor(fillColor) .strokeColor(strokeColor); } public CircleData() {} }
PolyLine数据模型
public class PolyLineData { private List<LatLngData> points; private int color; private float width; public PolyLineData(Polyline polyline) { this.points = new ArrayList<>(); for (LatLng latLng : polyline.getPoints()) { this.points.add(new LatLngData(latLng)); } this.color = polyline.getColor(); this.width = polyline.getWidth(); } public PolylineOptions toPolylineOptions() { List<LatLng> latLngList = new ArrayList<>(); for (LatLngData data : points) { latLngList.add(data.toLatLng()); } return new PolylineOptions() .addAll(latLngList) .color(color) .width(width); } // 辅助类:序列化LatLng public static class LatLngData { private double lat; private double lng; public LatLngData(LatLng latLng) { this.lat = latLng.latitude; this.lng = latLng.longitude; } public LatLng toLatLng() { return new LatLng(lat, lng); } public LatLngData() {} } public PolyLineData() {} }
步骤2:修改MapAnnotationObject
将原来的ArrayList<Marker>等替换为自定义数据模型的列表:
public class MapAnnotationObject { private ArrayList<MarkerData> markerDataList; private ArrayList<CircleData> circleDataList; private ArrayList<PolyLineData> polyLineDataList; // 构造方法、getter/setter public MapAnnotationObject(ArrayList<Marker> markers, ArrayList<Circle> circles, ArrayList<Polyline> polylines) { this.markerDataList = new ArrayList<>(); for (Marker marker : markers) { markerDataList.add(new MarkerData(marker)); } // 同理转换circles和polylines this.circleDataList = new ArrayList<>(); for (Circle circle : circles) { circleDataList.add(new CircleData(circle)); } this.polyLineDataList = new ArrayList<>(); for (Polyline polyline : polylines) { polyLineDataList.add(new PolyLineData(polyline)); } } public MapAnnotationObject() {} }
步骤3:保留原Gson转换器
现在你的MapAnnotationObjectConverter可以正常工作了,因为它处理的是纯POJO数据模型类,Gson能顺利序列化/反序列化:
public class MapAnnotationObjectConverter { private static Gson gson = new Gson(); @TypeConverter public static MapAnnotationObject fromString(String value) { return gson.fromJson(value, MapAnnotationObject.class); } @TypeConverter public static String fromMapAnnotationObject(MapAnnotationObject obj) { return gson.toJson(obj); } }
步骤4:从Room读取后重建地图元素
当从Room取出MapAnnotationObject后,遍历数据模型列表,调用对应的toXXXOptions()方法,将数据转换为地图元素添加到Map上:
// 示例:从Room读取后重建Marker MapAnnotationObject annotationObj = ...; // 从Room获取 for (MarkerData data : annotationObj.getMarkerDataList()) { googleMap.addMarker(data.toMarkerOptions()); } // 同理重建Circle和PolyLine
关键提醒
永远不要尝试序列化Android SDK或第三方SDK中的视图层对象,这类对象通常持有上下文、Native层引用或不可序列化的内部状态,只能提取核心数据保存,再通过数据重建对象。
内容的提问来源于stack exchange,提问作者Ben N
相关产品推荐
相关产品推荐

