【问题标题】:how to serialize an object of android.graphics.Path如何序列化 android.graphics.Path 的对象
【发布时间】:2011-06-22 15:04:42
【问题描述】:

我正在尝试将 Android.graphics.Path 的对象存储在内部设备内存中。有谁知道如何序列化 android.graphics.Path 对象?而且,还有其他存储 Path 对象的方法吗?谢谢。

【问题讨论】:

    标签: android serialization memory path internal


    【解决方案1】:

    我这样做的方法是从原始 Path 类中识别出我需要的方法,然后简单地覆盖这些方法,如下所示:

    public class CustomPath extends Path implements Serializable {
    
    private static final long serialVersionUID = -5974912367682897467L;
    
    private ArrayList<PathAction> actions = new ArrayList<CustomPath.PathAction>();
    
    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException{
        in.defaultReadObject();
        drawThisPath();
    }
    
    @Override
    public void moveTo(float x, float y) {
        actions.add(new ActionMove(x, y));
        super.moveTo(x, y);
    }
    
    @Override
    public void lineTo(float x, float y){
        actions.add(new ActionLine(x, y));
        super.lineTo(x, y);
    }
    
    private void drawThisPath(){
        for(PathAction p : actions){
            if(p.getType().equals(PathActionType.MOVE_TO)){
                super.moveTo(p.getX(), p.getY());
            } else if(p.getType().equals(PathActionType.LINE_TO)){
                super.lineTo(p.getX(), p.getY());
            }
        }
    }
    
    public interface PathAction {
        public enum PathActionType {LINE_TO,MOVE_TO};
        public PathActionType getType();
        public float getX();
        public float getY();
    }
    
    public class ActionMove implements PathAction, Serializable{
        private static final long serialVersionUID = -7198142191254133295L;
    
        private float x,y;
    
        public ActionMove(float x, float y){
            this.x = x;
            this.y = y;
        }
    
        @Override
        public PathActionType getType() {
            return PathActionType.MOVE_TO;
        }
    
        @Override
        public float getX() {
            return x;
        }
    
        @Override
        public float getY() {
            return y;
        }
    
    }
    
    public class ActionLine implements PathAction, Serializable{
        private static final long serialVersionUID = 8307137961494172589L;
    
        private float x,y;
    
        public ActionLine(float x, float y){
            this.x = x;
            this.y = y;
        }
    
        @Override
        public PathActionType getType() {
            return PathActionType.LINE_TO;
        }
    
        @Override
        public float getX() {
            return x;
        }
    
        @Override
        public float getY() {
            return y;
        }
    
    }
    }
    

    在我的示例中,我需要“moveTo”和“lineTo”,因此在这种情况下,我只需将绘图信息保存在一个列表中。此列表包含 Path 所需的绘图信息(我称之为“动作”),以便将绘图恢复为对象序列化之前的样子。然后,当我反序列化 CustomPath 类型的对象时,我确保让 the default serialization protocol 调用“drawThisPath”,因此重绘路径。

    【讨论】:

    • 好方法。我只是美化了你的代码。我的变种pastebin.com/CtJ5ibA7
    • 当我将自定义路径保存在文件中时,杀死应用程序然后打开它路径变为空。路径不为空,但操作为空,我无法重绘它。
    【解决方案2】:

    我刚刚设法解决了这个问题。我的应用程序基于 FingerPaintDemo,因此仅使用 moveTo 和 quadTo,但我认为您可以将此方法应用于任何 Path 函数。

    首先,扩展Path如下:

    import android.graphics.Path;
    
    import java.util.ArrayList;
    
    import java.io.Serializable;
    
    public class SerializablePath extends Path implements Serializable {
    
        private ArrayList<float[]> pathPoints;
    
        public SerializablePath() {
            super();
            pathPoints = new ArrayList<float[]>();
        }
    
        public SerializablePath(SerializablePath p) {
            super(p);
            pathPoints = p.pathPoints;
        }
    
        public void addPathPoints(float[] points) {
            this.pathPoints.add(points);
        }
    
        public void loadPathPointsAsQuadTo() {
            float[] initPoints = pathPoints.remove(0);
            this.moveTo(initPoints[0], initPoints[1]);
            for (float[] pointSet : pathPoints) {
                this.quadTo(pointSet[0], pointSet[1], pointSet[2], pointSet[3]);
            } 
        }
    }
    

    我认为我不需要粘贴实现代码,但如果您想查看,请告诉我。基本上就像你调用类似 myPath.quadTo(x1, y1, x2, y2) 一样,也调用 myPath.addPathPoints(new float[]{x1, y1, x2, y2})。

    像往常一样将对象序列化到磁盘,当你读回它时,一定要调用 myPath.loadPathPointsAsQuadTo()。

    【讨论】:

    • 我已经有一段时间没有看到这个了,但看看这是否有帮助:gist.github.com/2050745
    • @KazekageGaara brk3 已经提到,你需要调用 myPath.loadPathPointsAsQuadTo() 来恢复反序列化的路径。
    【解决方案3】:

    路径类没有什么特别之处。使用可以序列化任何实现了 Serializable 接口的类..

    Serializable 接口是一个Marker 接口。即它没有任何方法可以实现。它只是表示该对象可以被压缩为文件/内存,然后可以再次膨胀为活动对象

    您所做的只是创建一个扩展您的 android.graphics.Path 类并实现 Serializable 接口的类。然后使用这个类而不是你的 android.graphics.Path。然后你就可以对其应用序列化了。

    并查看以下链接以获取详细信息

    http://java.sun.com/developer/technicalArticles/Programming/serialization/

    希望这会有所帮助:)

    【讨论】:

    • 看来,反序列化后Path对象为空,例如没有任何线条和曲线。我认为,Path 对象是线条、矩形、弧形对象的容器,它们也应该是可序列化的。如果我是对的,路径序列化没有意义......请纠正我的任何人:)
    • 不幸的是,Javanator 的方法不起作用,代码将序列化,但在读回时路径为空。真的可以使用其他一些想法,因为我遇到了完全相同的问题。
    • 不可能:Path 只是 Skia 中原生路径的包装,无法提取
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-02-27
    • 1970-01-01
    • 2014-07-10
    • 2015-06-28
    • 2011-04-06
    • 1970-01-01
    相关资源
    最近更新 更多