I have a custom view which I used to draw different sizes and image to a canvas. It's great. So every time I draw something I am adding those information to an actionList.
When the user exit the application, I am saving this actionList as string to sharedPreference. At the time the user reopens the app I am getting this data and use Gson to convert it back List previous_drawn_paths and update actionList with this.
When I do this I am getting segmentation fault, but there is data and memory reference. I have attached code and tombstone logcat as well.
DrawingView.java
public class DrawingView extends View {
public enum Type {
PATH,
TEXT,
STAMP;
}
/**
* Different type of draw
*/
public enum Mode {
DRAW,
ERASER,
TEXT,
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, 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, action.getPositionX(), action.getPositionY(), 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, Path path, 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 positionX, float positionY) {
this.type = type;
this.text = text;
this.positionX = positionX;
this.positionY = positionY;
}
public DrawingAction(DrawingView.Type type, DrawingView.Stamper stamper, float positionX, 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)
Tombstone:
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, paused 3ms, 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, paused 3ms, 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, 12% free 80573K/91404K, paused 3ms, 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, paused 3ms, total 3ms
08-20 02:39:01.434 2064 2064 D dalvikvm: GC_FOR_ALLOC freed <1K, 9% free 83329K/91404K, paused 2ms, 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, paused 2ms, total 2ms
08-20 02:39:01.484 2064 2064 D dalvikvm: GC_FOR_ALLOC freed 16422K, 4% free 72306K/75312K, paused 4ms, 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, 4% free 83117K/86124K, 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, paused 2ms, 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, paused 4ms, 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, paused 2ms, 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, paused 2ms, 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, paused 2ms, 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, paused 3ms, 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, paused 3ms, 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, paused 3ms, 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, paused 2ms, total 3ms
08-20 02:39:03.084 2064 2064 F libc : Fatal signal 11 (SIGSEGV) at 0xb7bdb5a0 (code=1), thread 2064 (hourglass.drawing)
Problem in converting and saving objects like paint etc. I have a alternate solution for what you want to achieve:- You want following data list to save in preference:-
private DrawingView.Type type;
private Path path;
private Paint paint;
private String text;
private DrawingView.Stamper stamper;
private float positionX;
private float positionY;
In place of this you can use primitive data and implement parcelable. I mean you do not need to write whole paint object but values you are setting in paint object i.e. some primitive values. (similarly check for stamper and type)
The following is a working solution for saving paths and redrawing again, instead of imposing it on the Image and saving. In my case saved path is the problem not the paint object that i save.
PathPoint.Java
I am saving the co-ordinate of every action that was made by the user to this object and add it to a list in DrawingAction.java
public class PathPoint {
float startX;
float startY;
public float getStartX() {
return startX;
}
public void setStartX(float startX) {
this.startX = startX;
}
public float getStartY() {
return startY;
}
public void setStartY(float startY) {
this.startY = startY;
}
}
DrawingAction.java
Added the following piece of code to DrawingAction.java
private List<PathPoint> pts = new ArrayList<>();
public CorrectionView.Drawer getDrawer() {
return drawer;
}
public List<PathPoint> getPts() {
return pts;
}
public void setPts(List<PathPoint> pts) {
this.pts = pts;
}
public void addPts(PathPoint point)
{
this.pts.add(point);
//Adds touch co-ordinates to this list from Drawing View( on Touch Listener)
}
DrawingView.java
So In my DrawingView when the data is fectched from json, I am creating a fresh path and draw using the co_ordinates(PathPoint) from each actions. Thus I have able to achieve drawing from stored paths.
public void setPrevious_action_list(List<DrawingAction> previous_action_list) {
// updateActionListPath(previous_action_list);
this.previous_action_list = previous_action_list;
Path drawing_path;
for (DrawingAction action:previous_action_list)
{
drawing_path = new Path();
if (action.getType().equals(Type.PATH) && action.getDrawer().equals(Drawer.PEN) && action.getPts().size()>0)
{
//Setting starting path to path_point(0).startx and starty, if not set the points will be started from top corner.
drawing_path.moveTo(action.getPts().get(0).getStartX(),action.getPts().get(0).getStartY());
drawing_path.lineTo(action.getPts().get(0).getStartX(),action.getPts().get(0).getStartY());
drawing_path.moveTo(action.getPts().get(action.getPts(0).getStartX(),action.getPts().get(action.getPts(0).getStartY());
for (PathPoint path_point:action.getPts())
{
drawing_path.lineTo(path_point.getStartX(),path_point.getStartY());
}
action.setPath(drawing_path);
action.setPaint(this.drawPaint);
}
else if (action.getType().equals(Type.PATH) && action.getDrawer().equals(Drawer.LINE) && action.getPts().size()>0)
{
Log.d(TAG,"Using Line in setting action path");
drawing_path = new Path();
drawing_path.moveTo(action.getPts().get(0).getStartX(),action.getPts().get(0).getStartY());
for (PathPoint path_point:action.getPts())
{
drawing_path.lineTo(path_point.getStartX(),path_point.getStartY());
}
action.setPath(drawing_path);
action.setPaint(this.drawPaint);
}
else if (action.getType().equals(Type.PATH) && action.getDrawer().equals(Drawer.ELLIPSE) && action.getPts().size()>0)
{
if (action.getPts().size()==2)
{
drawing_path = new Path();
float start_x = action.getPts().get(0).getStartX();
float start_y = action.getPts().get(0).getStartY();
float end_x = action.getPts().get(1).getStartX();
float end_y = action.getPts().get(1).getStartY();
RectF rect = new RectF(start_x, start_y, end_x, end_y);
drawing_path.reset();
drawing_path.addOval(rect, Path.Direction.CCW);
action.setPath(drawing_path);
action.setPaint(this.drawPaint);
}
}
}
updateHistoryPath();
invalidate();
}
private void onActionMove(MotionEvent event) {
if (!isDown) {
return;
}
float x = event.getX();
float y = event.getY();
switch (this.mode) {
case DRAW:
DrawingAction drawing = this.getCurrentAction();
if(drawing.getType() == Type.PATH) {
Path path = drawing.getPath();
switch (this.drawer) {
case PEN:
path.lineTo(x, y);
PathPoint path_point = new PathPoint();
path_point.setStartX(x);
path_point.setStartY(y);
drawing.addPts(path_point);
drawing.setPath(path);
break;
case LINE:
path.reset();
path.moveTo(this.startX, this.startY);
path.lineTo(x, y);
// path_point = new PathPoint();
// path_point.setStartX(this.startX);
// path_point.setStartY(this.startY);
// drawing.addPts(path_point);
path_point = new PathPoint();
path_point.setStartX(x);
path_point.setStartY(y);
drawing.addPts(path_point);
drawing.setPath(path);
break;
case ELLIPSE:
RectF rect = new RectF(this.startX, this.startY, x, y);
path.reset();
path.addOval(rect, Path.Direction.CCW);
path_point =new PathPoint();
path_point.setStartY(this.startX);
path_point.setStartY(this.startY);
drawing.addPts(path_point);
path_point = new PathPoint();
path_point.setStartX(x);
path_point.setStartY(y);
drawing.addPts(path_point);
drawing.setPath(path);
break;
}
}
Based on logcat messages like this one:
... 2064 2064 I dalvikvm-heap: Grow heap (frag case) to 65.356MB for 65280012-byte allocation
you are allocating a lot of memory, possibly for some bitmaps that are too large for the device to handle. 65MB for example could store a 4000x4000 pixel bitmap.
Try disabling the part of your app that loads these resources, or replace them with something optimized for the size of the display.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With