我有一个自定义视图,我曾经用它绘制不同的大小和图像到画布.这很棒.所以每次我绘制的东西我都会将这些信息添加到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.我的意思是你不需要编写整个绘制对象,而是需要在绘制对象中设置的值,即一些原始值. (同样检查压模和类型)