android – 重新打开应用程序时,将画布路径保存到SharedPreference并在画布上重绘

我有一个自定义视图,我曾经用它绘制不同的大小和图像到画布.这很棒.所以每次我绘制的东西我都会将这些信息添加到actionList中.

用户退出应用程序时,我将此actionList作为字符串保存到sharedPreference.在用户重新打开应用程序时,我获取此数据并使用Gson将其转换回List prevIoUs_drawn_paths并使用此更新actionList.

当我这样做时,我得到分段错误,但有数据和内存参考.我也附加了代码和tombstone logcat.

DrawingView.java

public class DrawingView extends View {

    public enum Type {
        PATH,TEXT,STAMP;
    }

    /**
     * Different type of draw
     */
    public enum Mode {
        DRAW,ERASER,STAMP;
    }

    /**
     * Different Modes for Drawing
     */
    public enum Drawer {
        PEN,LINE,ELLIPSE;
    }

    /**
     * Different Modes of Stamps
     */
    public enum Stamper {
        STAR,THUMB;
    }

    private Context context = null;
    private Canvas canvas = null;
    private Bitmap bitmap = null;
    private int width;
    private int height;
    private int historyPointer = 0;
    private List<DrawingAction> prevIoUs_action_list = new ArrayList<>();
    private String TAG = this.getClass().getCanonicalName();

    public List<DrawingAction> getPrevIoUs_action_list() {
        return prevIoUs_action_list;
    }

    public void setPrevIoUs_action_list(List<DrawingAction> prevIoUs_action_list) {

        this.prevIoUs_action_list = prevIoUs_action_list;
        updateHistoryPath();

    }

    /**
     * Collection of different types of actions
     */
    private List<DrawingAction> actionLists = new ArrayList<>();

    public List<DrawingAction> getActionLists() {
        return actionLists;
    }

    /**
     * Flags for maintaining the states
     */
    private boolean enabled = false;
    private boolean isDown = false;
    private Mode mode = Mode.DRAW;
    private Drawer drawer = Drawer.PEN;
    private Stamper stamper = Stamper.STAR;

    private float startX = 0F;
    private float startY = 0F;
    private Paint drawPaint;
    private Paint erasePaint;
    private Paint textPaint;
    private Bitmap starPaint;
    private Bitmap thumbPaint;

    public DrawingView(Context context) {
        super(context);
        this.setup(context);
    }

    public DrawingView(Context context,AttributeSet attrs) {
        super(context,attrs);
        this.setup(context);
    }

    public DrawingView(Context context,AttributeSet attrs,int defStyleAttr) {
        super(context,attrs,defStyleAttr);
        this.setup(context);
    }

    private void setup(Context context) {
        this.context = context;
        createDrawPaint();
        createErasePaint();
        createTextPaint();
        createStamperPaint(context);
    }

    private void createDrawPaint() {
        this.drawPaint = new Paint();
        this.drawPaint.setAntiAlias(true);
        this.drawPaint.setStyle(Paint.Style.stroke);
        this.drawPaint.setstrokeWidth(10F);
        this.drawPaint.setstrokeCap(Paint.Cap.BUTT);
        this.drawPaint.setstrokeJoin(Paint.Join.MITER);
        this.drawPaint.setColor(Color.RED);
        this.drawPaint.setAlpha(255);
    }

    private void createErasePaint() {
        this.erasePaint = new Paint();
        this.erasePaint.setColor(Color.WHITE);
        this.erasePaint.setAlpha(255);
        this.erasePaint.setAntiAlias(true);
        this.erasePaint.setDither(true);
        this.erasePaint.setStyle(Paint.Style.stroke);
        this.erasePaint.setstrokeJoin(Paint.Join.ROUND);
        this.erasePaint.setstrokeCap(Paint.Cap.ROUND);
        this.erasePaint.setstrokeWidth(10F);
    }

    private void createTextPaint() {
        this.textPaint = new Paint();
        this.textPaint.setAntiAlias(true);
        this.textPaint.setStyle(Paint.Style.stroke);
        this.textPaint.setstrokeCap(Paint.Cap.BUTT);
        this.textPaint.setstrokeJoin(Paint.Join.MITER);
        this.textPaint.setTypeface(Typeface.DEFAULT);
        this.textPaint.setTextSize(56F);
        this.textPaint.setTextAlign(Paint.Align.RIGHT);
        this.drawPaint.setColor(Color.RED);
        this.textPaint.setstrokeWidth(0F);
    }

    private void createStamperPaint(Context context) {
        this.starPaint = BitmapFactory.decodeResource(context.getResources(),R.mipmap.stamp_star);
        this.thumbPaint = BitmapFactory.decodeResource(context.getResources(),R.mipmap.stamp_thumb);
    }

    private DrawingAction getCurrentAction() {
        return this.actionLists.get(this.historyPointer-1);
    }

    private void drawText(DrawingAction action,Canvas canvas) {
        String text = action.getText();
        if((text == null) || (text.length() <= 0)) {
            return;
        }

        float textx = action.getPositionX();
        float textY = action.getPositionY();

        Paint paintMeasureText = new Paint();

        float textLength = paintMeasureText.measureText(text);
        float lengthOfChar = textLength / (float) text.length();
        float restWidth = this.canvas.getWidth() - textx;  // text-align : right
        int numChars = (lengthOfChar <= 0) ? 1 : (int) Math.floor((double) (restWidth / lengthOfChar));  // The number of characters at 1 line
        int modNumChars = (numChars < 1) ? 1 : numChars;
        float y = textY;

        for (int i = 0,len = text.length(); i < len; i += modNumChars) {
            String substring = "";

            if ((i + modNumChars) < len) {
                substring = text.substring(i,(i + modNumChars));
            } else {
                substring = text.substring(i,len);
            }

            //Todo: Adjust according to the font size
            y += 56F;

            canvas.drawText(substring,textx,y,this.textPaint);
        }
    }

 private void updateHistory(DrawingAction action) {
        if (this.historyPointer == this.actionLists.size()) {
            this.actionLists.add(action);
            Log.d(TAG,"history pointer update"+this.historyPointer);
            this.historyPointer++;
        } else {
            // Removing the unused actions in history
            this.actionLists.set(this.historyPointer,action);
            this.historyPointer++;

            for (int i = this.historyPointer,size = this.actionLists.size(); i < size; i++) {
                this.actionLists.remove(this.historyPointer);
            }
        }
    }

    private void updateHistoryPath()
    {

        for(int index=0 ; index<prevIoUs_action_list.size(); index++)
        {
            Log.d(TAG,"adding canvas index from prevIoUs list"+index);
            if (prevIoUs_action_list.get(index).getType()!=null)
            {
                updateHistory(new DrawingAction(prevIoUs_action_list.get(index).getType(),prevIoUs_action_list.get(index).getPath(),prevIoUs_action_list.get(index).getPaint()));

            }
        }
    }


    public boolean undo() {
        if (this.historyPointer > 1) {
            this.historyPointer--;
            this.invalidate();
            return true;
        } else {
            return false;
        }
    }

    public boolean redo() {
        if (this.historyPointer < this.actionLists.size()) {
            this.historyPointer++;
            this.invalidate();
            return true;
        } else {
            return false;

        }
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        canvas.drawColor(Color.TRANSPARENT);

        if (this.bitmap != null) {
            canvas.drawBitmap(this.bitmap,0F,new Paint());
        }

        // this.historyPointer
        for (int i = 0; i < this.historyPointer; i++) {

            DrawingAction action = this.actionLists.get(i);
            Type type = action.getType();
            if(type == Type.PATH) {
                canvas.drawPath(action.getPath(),action.getPaint());
                Log.d("lingaraj","on draw history index"+i);

            }
            else if(type == Type.TEXT) {

                this.drawText(action,canvas);
            }
            else if(type == Type.STAMP) {
                Stamper stamper = action.getStamper();
                if(stamper == Stamper.STAR) {
                    canvas.drawBitmap(this.starPaint,action.getPositionX(),action.getPositionY(),new Paint());
                }
                else if(stamper == Stamper.THUMB) {
                    canvas.drawBitmap(this.thumbPaint,new Paint());
                }
            }
        }

        this.canvas = canvas;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec,int heightMeasureSpec) {
        int width = MeasureSpec.getSize(widthMeasureSpec);
        int height = MeasureSpec.getSize(heightMeasureSpec);
        setMeasuredDimension(width,height);
    }

    public void setCustomWidth(int width) {
        this.width = width;
    }

    public int getCustomWidth() {
        return this.width;
    }

    public void setCustomHeight(int height) {
        this.height = height;
    }

    public int getCustomHeight() {
        return this.height;
    }

    public void setEnabled(boolean enabled) {
        this.enabled = enabled;
    }

    public boolean getEnabled() {
        return this.enabled;
    }

    public void setMode(Mode mode) {
        this.mode = mode;
    }

    public Mode getMode() {
        return this.mode;
    }

    public void setDrawer(Drawer drawer) {
        this.drawer = drawer;
        this.mode = Mode.DRAW;
    }

    public void setStamper(Stamper stamper) {
        this.stamper = stamper;
        this.mode = Mode.STAMP;
    }

    public void setBitmap(Bitmap bitmap) {
        this.bitmap = bitmap;
        invalidate();
    }


}

DrawingAction.java:

public class DrawingAction {

    private DrawingView.Type type;
    private Path path;
    private Paint paint;
    private String text;
    private DrawingView.Stamper stamper;
    private float positionX;
    private float positionY;

    public DrawingAction(DrawingView.Type type,Path path,Paint paint) {
        this.type = type;
        this.path = path;
        this.paint = paint;
    }

    public DrawingAction(DrawingView.Type type,Paint paint,float positionX,float positionY) {
        this.type = type;
        this.path = path;
        this.paint = paint;
        this.positionX = positionX;
        this.positionY = positionY;
    }

    public DrawingAction(DrawingView.Type type,String text,float positionY) {
        this.type = type;
        this.text = text;
        this.positionX = positionX;
        this.positionY = positionY;
    }

    public DrawingAction(DrawingView.Type type,DrawingView.Stamper stamper,float positionY) {
        this.type = type;
        this.stamper = stamper;
        this.positionX = positionX;
        this.positionY = positionY;
    }

    public DrawingView.Type getType() {
        return type;
    }

    public Path getPath() {
        return path;
    }

    public void setPath(Path path) {
        this.path = path;
    }

    public Paint getPaint() {
        return  paint;
    }

    public void setPaint(Paint paint) {
        this.paint = paint;
    }

    public String getText() {
        return text;
    }

    public void setText(String text) {
        this.text = text;
    }

    public DrawingView.Stamper getStamper() {
        return stamper;
    }

    public void setStamper(DrawingView.Stamper stamper) {
        this.stamper = stamper;
    }

    public float getPositionX() {
        return positionX;
    }

    public void setPositionX(float positionX) {
        this.positionX = positionX;
    }

    public float getPositionY() {
        return  positionY;
    }

    public void setPositionY(float positionY) {
        this.positionY = positionY;
    }
}

MainActivity.java:

public class MainActivity extends AppCompatActivity {

    public static final String TAG = "Draw";
    private DrawingView drawing;
    private CanvasScroll scroll;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_correct);
        drawing = (DrawingView) findViewById(R.id.canvasDrawing);

        List<DrawingAction> drawing_action_list = new ArrayList<>();
        drawing_action_list = stringToList(Settings.getCorrectionPath(getApplicationContext()));
        disableScroll();
        if (drawing_action_list.isEmpty())
        {
            Log.d(TAG,"Drawing action list empty prevIoUs path not drawn");
        }
        else

        {
            drawing.setPrevIoUs_action_list(drawing_action_list);
            Log.d(TAG,"Drawing action list  prevIoUs path  drawn on canvas");

        }


    }

logcat的:

A/libc    : Fatal signal 11 (SIGSEGV) at 0xb7bdb5a0 (code=1),thread 2064 (hourglass.drawing)

墓碑:

backtrace:
  --------- log /dev/log/main
08-20 02:39:00.584  2064  2064 D dalvikvm: Not late-enabling CheckJNI (already on)
08-20 02:39:00.664  2064  2064 W dalvikvm: VFY: unable to find class referenced in signature (Landroid/view/SearchEvent;)
08-20 02:39:00.664  2064  2064 I dalvikvm: Could not find method android.view.Window$Callback.onSearchRequested,referenced from method android.support.v7.view.WindowCallbackWrapper.onSearchRequested
08-20 02:39:00.664  2064  2064 W dalvikvm: VFY: unable to resolve interface method 19785: Landroid/view/Window$Callback;.onSearchRequested (Landroid/view/SearchEvent;)Z
08-20 02:39:00.664  2064  2064 D dalvikvm: VFY: replacing opcode 0x72 at 0x0002
08-20 02:39:00.664  2064  2064 I dalvikvm: Could not find method android.view.Window$Callback.onWindowStartingActionMode,referenced from method android.support.v7.view.WindowCallbackWrapper.onWindowStartingActionMode
08-20 02:39:00.664  2064  2064 W dalvikvm: VFY: unable to resolve interface method 19789: Landroid/view/Window$Callback;.onWindowStartingActionMode (Landroid/view/ActionMode$Callback;I)Landroid/view/ActionMode;
08-20 02:39:00.664  2064  2064 D dalvikvm: VFY: replacing opcode 0x72 at 0x0002
08-20 02:39:00.684  2064  2064 I dalvikvm: Could not find method android.content.res.TypedArray.getChangingConfigurations,referenced from method android.support.v7.widget.TintTypedArray.getChangingConfigurations
08-20 02:39:00.684  2064  2064 W dalvikvm: VFY: unable to resolve virtual method 448: Landroid/content/res/TypedArray;.getChangingConfigurations ()I
08-20 02:39:00.684  2064  2064 D dalvikvm: VFY: replacing opcode 0x6e at 0x0002
08-20 02:39:00.684  2064  2064 I dalvikvm: Could not find method android.content.res.TypedArray.getType,referenced from method android.support.v7.widget.TintTypedArray.getType
08-20 02:39:00.694  2064  2064 W dalvikvm: VFY: unable to resolve virtual method 470: Landroid/content/res/TypedArray;.getType (I)I
08-20 02:39:00.694  2064  2064 D dalvikvm: VFY: replacing opcode 0x6e at 0x0002
08-20 02:39:00.734  2064  2064 D dalvikvm: GC_FOR_ALLOC freed 240K,9% free 3098K/3400K,paused 39ms,total 41ms
08-20 02:39:00.884  2064  2064 D dalvikvm: GC_FOR_ALLOC freed 9K,9% free 3121K/3400K,paused 3ms,total 3ms
08-20 02:39:00.934  2064  2064 I dalvikvm-heap: Grow heap (frag case) to 65.356MB for 65280012-byte allocation
08-20 02:39:00.954  2064  2072 D dalvikvm: GC_FOR_ALLOC freed <1K,1% free 66870K/67152K,paused 16ms,total 16ms
08-20 02:39:01.254  2064  2064 D dalvikvm: GC_FOR_ALLOC freed 46K,1% free 66909K/67164K,paused 4ms,total 5ms
08-20 02:39:01.264  2064  2064 I dalvikvm-heap: Grow heap (frag case) to 75.718MB for 10825612-byte allocation
08-20 02:39:01.284  2064  2072 D dalvikvm: GC_FOR_ALLOC freed 2K,1% free 77479K/77736K,paused 17ms,total 17ms
08-20 02:39:01.314  2064  2064 Din.co.hourglass.drawing.MainActivity:  Original pixels3400/796
08-20 02:39:01.324  2064  2064 Din.co.hourglass.drawing.MainActivity: Scaled pixels1700/398
08-20 02:39:01.324  2064  2064 D dalvikvm: GC_FOR_ALLOC freed 1K,1% free 77478K/77736K,total 3ms
08-20 02:39:01.324  2064  2064 I dalvikvm-heap: Grow heap (frag case) to 78.296MB for 2706412-byte allocation
08-20 02:39:01.344  2064  2072 D dalvikvm: GC_FOR_ALLOC freed <1K,1% free 80121K/80380K,paused 15ms,total 15ms
08-20 02:39:01.374  2064  2064 D dalvikvm: GC_FOR_ALLOC freed 10572K,14% free 69550K/80380K,total 3ms
08-20 02:39:01.374  2064  2064 I dalvikvm-heap: Grow heap (frag case) to 78.738MB for 11288012-byte allocation
08-20 02:39:01.424  2064  2064 D dalvikvm: GC_FOR_ALLOC freed <1K,12% free 80573K/91404K,paused 2ms,total 2ms
08-20 02:39:01.424  2064  2064 Din.co.hourglass.drawing.MainActivity:  Original pixels3400/830
08-20 02:39:01.424  2064  2064 Din.co.hourglass.drawing.MainActivity: Scaled pixels1700/415
08-20 02:39:01.424  2064  2064 D dalvikvm: GC_FOR_ALLOC freed <1K,total 3ms
08-20 02:39:01.434  2064  2064 I dalvikvm-heap: Grow heap (frag case) to 81.429MB for 2822012-byte allocation
08-20 02:39:01.434  2064  2064 D dalvikvm: GC_FOR_ALLOC freed <1K,9% free 83329K/91404K,total 3ms
08-20 02:39:01.434  2064  2064 D dalvikvm: GC_FOR_ALLOC freed <1K,total 3ms
08-20 02:39:01.434  2064  2064 I dalvikvm-heap: Grow heap (frag case) to 86.701MB for 5528412-byte allocation
08-20 02:39:01.444  2064  2064 D dalvikvm: GC_FOR_ALLOC freed <1K,3% free 88728K/91404K,total 2ms
08-20 02:39:01.484  2064  2064 D dalvikvm: GC_FOR_ALLOC freed 16422K,4% free 72306K/75312K,total 4ms
08-20 02:39:01.484  2064  2064 I dalvikvm-heap: Grow heap (frag case) to 81.221MB for 11070412-byte allocation
08-20 02:39:01.534  2064  2064 D dalvikvm: GC_FOR_ALLOC freed <1K,4% free 83117K/86124K,paused 10ms,total 10ms
08-20 02:39:01.534  2064  2064 Din.co.hourglass.drawing.MainActivity:  Original pixels3400/814
08-20 02:39:01.534  2064  2064 Din.co.hourglass.drawing.MainActivity: Scaled pixels1700/407
08-20 02:39:01.544  2064  2064 D dalvikvm: GC_FOR_ALLOC freed <1K,paused 8ms,total 8ms
08-20 02:39:01.544  2064  2064 I dalvikvm-heap: Grow heap (frag case) to 83.861MB for 2767612-byte allocation
08-20 02:39:01.554  2064  2064 D dalvikvm: GC_FOR_ALLOC freed <1K,1% free 85819K/86124K,paused 12ms,total 12ms
08-20 02:39:01.564  2064  2064 D dalvikvm: GC_FOR_ALLOC freed 10811K,1% free 75008K/75312K,total 3ms
08-20 02:39:01.564  2064  2064 I dalvikvm-heap: Grow heap (frag case) to 81.215MB for 8296012-byte allocation
08-20 02:39:01.574  2064  2064 D dalvikvm: GC_FOR_ALLOC freed <1K,1% free 83110K/83416K,paused 5ms,total 6ms
08-20 02:39:01.594  2064  2064 D dalvikvm: GC_FOR_ALLOC freed 8101K,11% free 75009K/83416K,total 4ms
08-20 02:39:01.594  2064  2064 I dalvikvm-heap: Grow heap (frag case) to 77.350MB for 4243212-byte allocation
08-20 02:39:01.614  2064  2064 D dalvikvm: GC_FOR_ALLOC freed <1K,6% free 79152K/83416K,total 2ms
08-20 02:39:01.614  2064  2064 Din.co.hourglass.drawing.MainActivity:  Original pixels3400/312
08-20 02:39:01.614  2064  2064 Din.co.hourglass.drawing.MainActivity: Scaled pixels1700/156
08-20 02:39:01.614  2064  2064 D dalvikvm: GC_FOR_ALLOC freed 4144K,9% free 76045K/83416K,total 3ms
08-20 02:39:01.614  2064  2064 I dalvikvm-heap: Grow heap (frag case) to 83.239MB for 9356812-byte allocation
08-20 02:39:01.624  2064  2064 D dalvikvm: GC_FOR_ALLOC freed <1K,8% free 85182K/92556K,total 3ms
08-20 02:39:01.624  2064  2064 Din.co.hourglass.drawing.MainActivity: Bitmap Merged
08-20 02:39:01.714  2064  2064 D         : HostConnection::get() New Host Connection established 0xb833f3c0,tid 2064
08-20 02:39:02.844  2064  2064 D dalvikvm: GC_FOR_ALLOC freed 18381K,8% free 67150K/72492K,total 8ms
08-20 02:39:02.844  2064  2064 I dalvikvm-heap: Grow heap (frag case) to 77.371MB for 12312340-byte allocation
08-20 02:39:02.884  2064  2064 D dalvikvm: GC_FOR_ALLOC freed 8K,7% free 79165K/84516K,total 3ms
08-20 02:39:02.904  2064  2064 D lingaraj: adding canvas index from prevIoUs list0
08-20 02:39:02.904  2064  2064 D lingaraj: history pointer update0
08-20 02:39:02.904  2064  2064 D lingaraj: adding canvas index from prevIoUs list1
08-20 02:39:02.904  2064  2064 D lingaraj: history pointer update1
08-20 02:39:02.914  2064  2064 D Drawing: Drawing action list  prevIoUs path  drawn on canvas
08-20 02:39:03.074  2064  2064 D dalvikvm: GC_FOR_ALLOC freed 337K,7% free 79264K/84516K,total 4ms
08-20 02:39:03.074  2064  2064 I dalvikvm-heap: Grow heap (frag case) to 86.820MB for 9815116-byte allocation
08-20 02:39:03.084  2064  2064 D dalvikvm: GC_FOR_ALLOC freed <1K,6% free 88849K/94104K,total 3ms
08-20 02:39:03.084  2064  2064 F libc    : Fatal signal 11 (SIGSEGV) at 0xb7bdb5a0 (code=1),thread 2064 (hourglass.drawing)

解决方法

转换和保存油漆等对象时出现问题
我有一个替代解决方案,你想要实现的目标: –
您希望以下数据列表优先保存: –
private DrawingView.Type type;
    private Path path;
    private Paint paint;
    private String text;
    private DrawingView.Stamper stamper;
    private float positionX;
    private float positionY;

取而代之,您可以使用原始数据并实现parcelable.我的意思是你不需要编写整个绘制对象,而是需要在绘制对象中设置的值,即一些原始值. (同样检查压模和类型)

相关文章

这篇“android轻量级无侵入式管理数据库自动升级组件怎么实现...
今天小编给大家分享一下Android实现自定义圆形进度条的常用方...
这篇文章主要讲解了“Android如何解决字符对齐问题”,文中的...
这篇文章主要介绍“Android岛屿数量算法怎么使用”的相关知识...
本篇内容主要讲解“Android如何开发MQTT协议的模型及通信”,...
本文小编为大家详细介绍“Android数据压缩的方法是什么”,内...