java - StackOverflowError while saving and loading my object in android -


i'm writing android program , ran problem.

my program serves create graphs, run specific algorithms on them (dijsktra, belmanford, etc.), save graphs sd card , loading them back.

the problem: if save little bigger, more complex graph stackoverflow error..

serialization:

public void createexternalstoragepublicgraph(string filename) {     file dir = environment.getexternalstoragepublicdirectory("grapher");      try {         if (!dir.exists()) {             dir.mkdirs();         }         file file = new file(dir, filename);         fileoutputstream fileoutputstream = new fileoutputstream(file);         objectoutputstream objectoutputstream = new objectoutputstream(fileoutputstream);         objectoutputstream.writeobject(graphdrawerview.getgraph());         objectoutputstream.close();      } catch (ioexception e) {         log.w("externalstorage", "error writing" + filename, e);     }  } 

deserialization:

public graph loadexternalstoragepublicgraph(string filename) {     file file = new file(environment.getexternalstoragepublicdirectory("grapher"), filename);     graph graph = null;      try {          fileinputstream fint = new fileinputstream(file);         objectinputstream ois = new objectinputstream(fint);         graph = (graph) ois.readobject();         ois.close();      } catch (exception e) {         log.e("deserialization error:", e.getmessage());         e.printstacktrace();     }     return graph; } 

graph class:

package com.cslqaai.grapher;  import android.util.log; import java.io.serializable; import java.util.linkedlist;  public class graph implements serializable {      private string name;     private boolean directed = false;     private boolean weighted = false;     private linkedlist<vertex> vertexes = new linkedlist<vertex>();     private linkedlist<edge> edges = new linkedlist<edge>();      // --------------------------------------------------------------------------------------------------------------------------------------     public graph(boolean weighted, boolean directed) {         this.directed = directed;         this.weighted = weighted;     }      // --------------------------------------------------------------------------------------------------------------------------------------     public void add(abstractgraphobject ago) {         if (ago instanceof vertex) {             this.vertexes.add((vertex) ago);         } else if (ago instanceof edge) {              this.edges.add((edge) ago);         } else {         }     }      // --------------------------------------------------------------------------------------------------------------------------------------     public boolean isweighted() {         return this.weighted;     }      // --------------------------------------------------------------------------------------------------------------------------------------     public boolean isdirected() {         return this.directed;     }      // --------------------------------------------------------------------------------------------------------------------------------------\     public linkedlist<edge> getedges() {         return this.edges;     }      // --------------------------------------------------------------------------------------------------------------------------------------     public linkedlist<vertex> getvertexes() {         return this.vertexes;     }      // --------------------------------------------------------------------------------------------------------------------------------------     public void reset() {         (int = 0; < this.edges.size(); i++) {             this.edges.get(i).setcolortodefault();         }     }      // --------------------------------------------------------------------------------------------------------------------------------------     void remove(abstractgraphobject ago) {         if (ago instanceof vertex) {             log.d("graph", "remove vertex graph");             this.vertexes.remove((vertex) ago);         } else if (ago instanceof edge) {             log.d("graph", "remove edge graph");             this.edges.remove((edge) ago);         }     }     // --------------------------------------------------------------------------------------------------------------------------------------      public void setweighted(boolean weighted) {         this.weighted = weighted;     }     // --------------------------------------------------------------------------------------------------------------------------------------      public void setdirected(boolean directed) {         this.directed = directed;     }     // --------------------------------------------------------------------------------------------------------------------------------------      public string getname() {         return this.name;     }     // --------------------------------------------------------------------------------------------------------------------------------------      public void setname(string name) {         this.name = name;     } } // ---------------------------------------------------------------------------------------------------------------------------------------- 

vertex class:

package com.cslqaai.grapher; import android.graphics.canvas; import android.graphics.color; import android.graphics.paint; import android.graphics.typeface; import java.util.arraylist; import java.util.iterator; import java.util.linkedlist;  public class vertex extends abstractgraphobject {  public static final int radius_size = 20; public static final int surrounding_radius_size = 30; private static layer defaultvertexlayer = abstractgraphobject.defaultlayer; private static int no = 0; private static paint paint = new paint(paint.anti_alias_flag); private static paint paintcolored = new paint(paint.anti_alias_flag); private static paint textpaint = new paint(paint.anti_alias_flag); private static paint textbgpaint = new paint(paint.anti_alias_flag); private final int id; private string name = null; private coord coord; private coord cachedcoord; private arraylist<edge> edges = new arraylist<edge>(); private boolean colored = false;  // -------------------------------------------------------------------------------------------------------------------------------------- static {     vertex.paint.setcolor(0xff0ff5f5);     vertex.paintcolored.setcolor(color.red);     vertex.textpaint.setstyle(paint.style.fill);     vertex.textpaint.setcolor(color.black);     vertex.textpaint.settextalign(paint.align.center);     vertex.textpaint.settextsize(20);     vertex.textpaint.settypeface(typeface.create("helvetica", typeface.bold));     vertex.textbgpaint.setstyle(paint.style.fill);     vertex.textbgpaint.setcolor(0xff0ff5f5); }  // -------------------------------------------------------------------------------------------------------------------------------------- public vertex(coord coord) {     super(vertex.defaultvertexlayer);     this.id = vertex.no++;     this.coord = coord;     this.recalculate(); }  // -------------------------------------------------------------------------------------------------------------------------------------- public vertex(int x, int y) {     this(new coord(x, y)); }  // -------------------------------------------------------------------------------------------------------------------------------------- @override public void recalculate() {     this.cachedcoord = new coord(math.round((vertex.basex + this.coord.getx()) * vertex.scalefactor), math.round((vertex.basey + this.coord.gety()) * vertex.scalefactor));     this.onscreen = this.cachedcoord.getx() + vertex.radius_size > 0 && this.cachedcoord.gety() + vertex.radius_size > 0             && this.cachedcoord.getx() - vertex.radius_size < vertex.screenwidth && this.cachedcoord.gety() - vertex.radius_size < this.cachedcoord.gety(); }  // -------------------------------------------------------------------------------------------------------------------------------------- public coord getcoord() {     return this.coord; }  // -------------------------------------------------------------------------------------------------------------------------------------- public coord getcachedcoord() {     return this.cachedcoord; }  // -------------------------------------------------------------------------------------------------------------------------------------- public int getradiussize() {     return vertex.radius_size; }  // -------------------------------------------------------------------------------------------------------------------------------------- @override public void draw(canvas canvas) {     this.recalculate();      if (!this.onscreen) {         return;     }      canvas.drawcircle(this.cachedcoord.getx(), this.cachedcoord.gety(), vertex.radius_size * vertex.scalefactor, vertex.paint);     if (this.name != null) {         float width = vertex.textpaint.measuretext(this.name) + 10;         float height = vertex.textpaint.gettextsize() + 5;         canvas.drawrect(this.cachedcoord.getx() - width / 2, this.cachedcoord.gety() - height / 2, this.cachedcoord.getx() + width / 2, this.cachedcoord.gety() + height / 2, vertex.textbgpaint);         canvas.drawtext(this.name, this.cachedcoord.getx(), this.cachedcoord.gety() + height * 0.25f, vertex.textpaint);     } } // --------------------------------------------------------------------------------------------------------------------------------------  private boolean searchingcoordon(float radius, float px, float py) {     return this.onscreen && ((math.pow(px - this.cachedcoord.getx(), 2) + math.pow(py - this.cachedcoord.gety(), 2)) < (math.pow(radius * vertex.scalefactor, 2))); }  // -------------------------------------------------------------------------------------------------------------------------------------- public boolean isoncoord(float px, float py) {     return this.searchingcoordon(vertex.radius_size, px, py); }  // -------------------------------------------------------------------------------------------------------------------------------------- public boolean isincoordsurroundings(float px, float py) {     return this.searchingcoordon(vertex.surrounding_radius_size, px, py); } // --------------------------------------------------------------------------------------------------------------------------------------  public void addedge(edge edge) {     if (!this.edges.contains(edge)) {         this.edges.add(edge);     } }  // -------------------------------------------------------------------------------------------------------------------------------------- public arraylist<edge> getedges() {     return this.edges; }  // -------------------------------------------------------------------------------------------------------------------------------------- public void removeedge(edge edge) {     if (this.edges.contains(edge)) {         this.edges.remove(edge);     } }  // -------------------------------------------------------------------------------------------------------------------------------------- public boolean hasedge(edge edge) {     return this.edges.contains(edge); }  // -------------------------------------------------------------------------------------------------------------------------------------- public static void setdefaultlayer(layer layer) {     vertex.defaultvertexlayer = layer; }  // -------------------------------------------------------------------------------------------------------------------------------------- public static layer getdefaultlayer() {     return vertex.defaultvertexlayer; }  // -------------------------------------------------------------------------------------------------------------------------------------- public static void remove(vertex vertex) {     iterator<edge> edges = vertex.getedges().iterator();     while (edges.hasnext()) {         edge e = edges.next();         edges.remove();         edge.remove(e);     }      vertex.defaultvertexlayer.remove(vertex);     if (vertex.graph != null) {         vertex.graph.remove(vertex);     } }  // -------------------------------------------------------------------------------------------------------------------------------------- public boolean hasname() {     return this.name != null; }  // -------------------------------------------------------------------------------------------------------------------------------------- public void setname(string name) {     this.name = name; }  // -------------------------------------------------------------------------------------------------------------------------------------- public string getname() {     return this.name; }  // -------------------------------------------------------------------------------------------------------------------------------------- public int getid() {     return this.id; } // -------------------------------------------------------------------------------------------------------------------------------------- } 

edge class:

package com.cslqaai.grapher;  import android.graphics.*; import java.util.arraylist; import java.util.linkedlist;  public class edge extends abstractgraphobject {  public static final float stroke_width = 5f; public static final float sensor_width = 50f; public static final float surrounding_sensor_width = 15f; public static final float triangle_size = 8f; private static paint paint = new paint(paint.anti_alias_flag); private static paint paintcolored = new paint(paint.anti_alias_flag); private static paint textpaint = new paint(paint.anti_alias_flag); private static paint textbgpaint = new paint(paint.anti_alias_flag); private static layer defaultedgelayer = abstractgraphobject.defaultlayer; private static int no = 0; private final int id; private int weight = 1; private coord cachedsourcecoord; private coord cachedtargetcoord; private vertex sourcevertex; private vertex targetvertex; private coord weightcoord; private boolean colored = false;  // -------------------------------------------------------------------------------------------------------------------------------------- static {     edge.paint.setcolor(0xffffffff);     edge.paint.setstrokewidth(edge.stroke_width * edge.scalefactor);     edge.paint.setstrokecap(paint.cap.round);     edge.paint.setstyle(paint.style.fill_and_stroke);     edge.paintcolored.setcolor(0xffff0000);     edge.paintcolored.setstrokewidth(edge.stroke_width * edge.scalefactor);     edge.paintcolored.setstrokecap(paint.cap.round);     edge.paintcolored.setstyle(paint.style.fill_and_stroke);     edge.textpaint.setstyle(paint.style.fill);     edge.textpaint.setcolor(color.black);     edge.textpaint.settextalign(paint.align.center);     edge.textpaint.settextsize(20);     edge.textpaint.settypeface(typeface.create("helvetica", typeface.bold));     edge.textbgpaint.setstyle(paint.style.fill);     edge.textbgpaint.setcolor(color.white); }  // -------------------------------------------------------------------------------------------------------------------------------------- public edge(vertex sourcevertex, vertex targetvertex) {     super(edge.defaultedgelayer);     this.id = edge.no++;     this.sourcevertex = sourcevertex;     this.targetvertex = targetvertex;     this.sourcevertex.addedge(this);     this.targetvertex.addedge(this);     this.recalculate(); }  // -------------------------------------------------------------------------------------------------------------------------------------- public void recalculate() {     this.cachedsourcecoord = new coord(math.round((edge.basex + this.sourcevertex.getcoord().getx()) * edge.scalefactor), math.round((edge.basey + this.sourcevertex.getcoord().gety()) * edge.scalefactor));     this.cachedtargetcoord = new coord(math.round((edge.basex + this.targetvertex.getcoord().getx()) * edge.scalefactor), math.round((edge.basey + this.targetvertex.getcoord().gety()) * edge.scalefactor));      line line = new line(this.cachedsourcecoord, this.cachedtargetcoord);     this.weightcoord = line.getmiddle();      this.onscreen = edge.screenbottomline.hasintersection(line)             || edge.screenleftline.hasintersection(line)             || edge.screenrightline.hasintersection(line)             || edge.screentopline.hasintersection(line)             || this.cachedsourcecoord.getx() > 0 && this.cachedsourcecoord.getx() < edge.screenwidth && this.cachedsourcecoord.gety() > 0 && this.cachedsourcecoord.gety() < edge.screenheight             || this.cachedtargetcoord.getx() > 0 && this.cachedtargetcoord.getx() < edge.screenwidth && this.cachedtargetcoord.gety() > 0 && this.cachedtargetcoord.gety() < edge.screenheight; }  // -------------------------------------------------------------------------------------------------------------------------------------- @override public void draw(canvas canvas) {     this.recalculate();      if (!this.onscreen) {         return;     }      canvas.drawline(this.cachedsourcecoord.getx(), this.cachedsourcecoord.gety(), this.cachedtargetcoord.getx(), this.cachedtargetcoord.gety(), this.colored ? edge.paintcolored : edge.paint);      if (edge.graph != null && edge.graph.isdirected()) {         line line = new line(this.cachedsourcecoord, this.cachedtargetcoord);         coord v = line.getvector();         float t = (float) ((vertex.radius_size + 5) / math.sqrt(math.pow(v.getx(), 2) + math.pow(v.gety(), 2)));         coord t1 = new coord((int) (this.cachedtargetcoord.getx() - t * v.getx()), (int) (this.cachedtargetcoord.gety() - t * v.gety()));         if (!line.isonline(t1)) {             t1 = new coord((int) (this.cachedtargetcoord.getx() + t * v.getx()), (int) (this.cachedtargetcoord.gety() + t * v.gety()));         }         t = (float) ((vertex.radius_size + 5 + edge.triangle_size) / math.sqrt(math.pow(v.getx(), 2) + math.pow(v.gety(), 2)));         coord p = new coord((int) (this.cachedtargetcoord.getx() - t * v.getx()), (int) (this.cachedtargetcoord.gety() - t * v.gety()));         if (!line.isonline(p)) {             p = new coord((int) (this.cachedtargetcoord.getx() + t * v.getx()), (int) (this.cachedtargetcoord.gety() + t * v.gety()));         }         v = line.getnormalvector().getvector();         t = (float) ((edge.triangle_size) / math.sqrt(math.pow(v.getx(), 2) + math.pow(v.gety(), 2)));         coord t2 = new coord((int) (p.getx() - t * v.getx()), (int) (p.gety() - t * v.gety()));         coord t3 = new coord((int) (p.getx() + t * v.getx()), (int) (p.gety() + t * v.gety()));         path path = new path();          path.setfilltype(path.filltype.even_odd);         path.moveto(t1.getx(), t1.gety());         path.lineto(t2.getx(), t2.gety());         path.lineto(t3.getx(), t3.gety());         path.lineto(t1.getx(), t1.gety());         path.close();          canvas.drawpath(path, edge.paint);     }      if (edge.graph != null && edge.graph.isweighted()) {         float width = edge.textpaint.measuretext(integer.tostring(this.weight)) + 10;         float height = edge.textpaint.gettextsize() + 5;         canvas.drawrect(this.weightcoord.getx() - width / 2, this.weightcoord.gety() - height / 2, this.weightcoord.getx() + width / 2, this.weightcoord.gety() + height / 2, edge.textbgpaint);         canvas.drawtext(integer.tostring(this.weight), this.weightcoord.getx(), this.weightcoord.gety() + height * 0.25f, edge.textpaint);     } }  // -------------------------------------------------------------------------------------------------------------------------------------- private boolean searchingcoordon(float distance, float px, float py) {     coord p = new coord((int) px, (int) py);     coord v = (new line(this.cachedsourcecoord, this.cachedtargetcoord)).getnormalvector().getvector();     float t = (float) (distance / math.sqrt(math.pow(v.getx(), 2) + math.pow(v.gety(), 2)));     coord c1 = new coord((int) (this.cachedsourcecoord.getx() - t * v.getx()), (int) (this.cachedsourcecoord.gety() - t * v.gety()));     coord c2 = new coord((int) (this.cachedsourcecoord.getx() + t * v.getx()), (int) (this.cachedsourcecoord.gety() + t * v.gety()));     coord c3 = new coord((int) (this.cachedtargetcoord.getx() - t * v.getx()), (int) (this.cachedtargetcoord.gety() - t * v.gety()));     coord v1 = new coord(c2.getx() - c1.getx(), c2.gety() - c1.gety());     coord v2 = new coord(c3.getx() - c1.getx(), c3.gety() - c1.gety());     v = coord.minus(p, c1);      return this.onscreen             && 0 <= coord.dotproduct(v, v1) && coord.dotproduct(v, v1) <= coord.dotproduct(v1, v1)             && 0 <= coord.dotproduct(v, v2) && coord.dotproduct(v, v2) <= coord.dotproduct(v2, v2); }  // -------------------------------------------------------------------------------------------------------------------------------------- public boolean isoncoord(float px, float py) {     return this.searchingcoordon(edge.sensor_width / 2, px, py); }  // -------------------------------------------------------------------------------------------------------------------------------------- public boolean isincoordsurroundings(float px, float py) {     return this.searchingcoordon(edge.surrounding_sensor_width / 2, px, py); }  // -------------------------------------------------------------------------------------------------------------------------------------- public vertex getsourcevertex() {     return this.sourcevertex; }  // -------------------------------------------------------------------------------------------------------------------------------------- public vertex gettargetvertex() {     return this.targetvertex; }  // -------------------------------------------------------------------------------------------------------------------------------------- public static void setdefaultlayer(layer layer) {     edge.defaultedgelayer = layer; }  // -------------------------------------------------------------------------------------------------------------------------------------- public static layer getdefaultlayer() {     return edge.defaultedgelayer; }  // -------------------------------------------------------------------------------------------------------------------------------------- public static void remove(edge edge) {     edge.getsourcevertex().removeedge(edge);     edge.gettargetvertex().removeedge(edge);     edge.defaultedgelayer.remove(edge);     if (edge.graph != null) {         edge.graph.remove(edge);     } }  // -------------------------------------------------------------------------------------------------------------------------------------- public void setweight(int weight) {     this.weight = weight; }  // -------------------------------------------------------------------------------------------------------------------------------------- public int getweight() {     return this.weight; }  // -------------------------------------------------------------------------------------------------------------------------------------- public int getid() {     return this.id; }  // -------------------------------------------------------------------------------------------------------------------------------------- public void setcolored() {     this.colored = true; }  // -------------------------------------------------------------------------------------------------------------------------------------- public void setcolortodefault() {     this.colored = false; }  // -------------------------------------------------------------------------------------------------------------------------------------- public static arraylist<edge> getedgesbetween(vertex v1, vertex v2) {     arraylist<edge> edges = v1.getedges();     arraylist<edge> edgesret = new arraylist<edge>();     (edge edge : edges) {         if (v2.hasedge(edge)) {             edgesret.add(edge);         }     }     return edges; } // -------------------------------------------------------------------------------------------------------------------------------------- } 

the reason "normal" serialization each entry recursively invoke writeobject(e), , long lists give stackoverflowerror. iterative serialization avoids this.

i found on stackoverflow. think problem related long linkedlists..

any ideas, advices how serialize , deserialize graph object?

thank in advance!

as fast fix, try substuting linkedlist list implemetnations arraylists. didn't give enough details (the exact exception , implementations of vertexes , edges helpful), quoted might right: run out of memory because of recursive calls. didn't try, arraylist default java serialization avoid issue.

for solution, serialization methods of graph objects re-implemented, or tested , more memory efficient library used (eg. kryo).

this question helpful.


Comments

Popular posts from this blog

Perl - how to grep a block of text from a file -

delphi - How to remove all the grips on a coolbar if I have several coolbands? -

javascript - Animating array of divs; only the final element is modified -