You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 17:20:18