Android/Java creating a helper class to create graphs -
goal:
to create helper class graph generation
background:
i have 3 fragments each collect sensor data (accelerometer, gyroscope, rotation) , plots graph using graphview. here code looks 1 of fragments (this code works correctly):
public class gyroscopefragment extends fragment implements sensoreventlistener { private final short type_gyroscope = sensor.type_gyroscope; private final short poll_frequency = 100; //in milliseconds private final short max_points_displayed = 50; private sensormanager sensormanager; private sensor sensor; private sensor gyroscope; private long lastupdate = -1; float curgyrox; float curgyroy; float curgyroz; private linegraphseries<datapoint> gyroxseries; private linegraphseries<datapoint> gyroyseries; private linegraphseries<datapoint> gyrozseries; private double graphxtime = 1d; public gyroscopefragment() { // required empty public constructor } @override public view oncreateview(layoutinflater inflater, viewgroup container, bundle savedinstancestate) { // inflate layout fragment view view = inflater.inflate(r.layout.fragment_gyroscope, container, false); //set nav drawer item highlight mainactivity mainactivity = (mainactivity) getactivity(); mainactivity.navigationview.setcheckeditem(r.id.nav_gyroscope); //set actionbar title mainactivity.settitle("gyroscope"); //sensor manager sensormanager = (sensormanager) getcontext().getsystemservice(context.sensor_service); gyroscope = (sensor) sensormanager.getdefaultsensor(type_gyroscope); return view; } @override public void onresume() { super.onresume(); sensormanager.registerlistener(this, gyroscope, sensormanager.sensor_delay_fastest); //create graph graphview gyrograph = (graphview) getview().findviewbyid(r.id.gyrograph); gyrograph.getlegendrenderer().setvisible(true); gyrograph.getlegendrenderer().setfixedposition(0,0); gyrograph.getgridlabelrenderer().sethighlightzerolines(false); gyroxseries = new linegraphseries<datapoint>(); gyroyseries = new linegraphseries<datapoint>(); gyrozseries = new linegraphseries<datapoint>(); gyroxseries.settitle("x"); gyroyseries.settitle("y"); gyrozseries.settitle("z"); gyroxseries.setcolor(color.red); gyroyseries.setcolor(color.green); gyrozseries.setcolor(color.blue); gyrograph.addseries(gyroxseries); gyrograph.addseries(gyroyseries); gyrograph.addseries(gyrozseries); gyrograph.getviewport().setyaxisboundsmanual(true); gyrograph.getviewport().setminy(-10); gyrograph.getviewport().setmaxy(10); gyrograph.getviewport().setxaxisboundsmanual(true); gyrograph.getviewport().setminx(0); gyrograph.getviewport().setmaxx(max_points_displayed); } @override public void onpause() { super.onpause(); sensormanager.unregisterlistener(this); } @override public void ondestroy() { super.ondestroy(); sensormanager.unregisterlistener(this); } @override public void onlowmemory() { super.onlowmemory(); sensormanager.unregisterlistener(this); } @override public void onsensorchanged(sensorevent event) { sensor = event.sensor; curgyrox = event.values[0]; curgyroy = event.values[1]; curgyroz = event.values[2]; long curtime = system.currenttimemillis(); long difftime = (curtime - lastupdate); // allow 1 update every poll_frequency. if (difftime > poll_frequency) { lastupdate = curtime; graphxtime += 1d; gyroxseries.appenddata(new datapoint(graphxtime, curgyrox), true, max_points_displayed); gyroyseries.appenddata(new datapoint(graphxtime, curgyroy), true, max_points_displayed); gyrozseries.appenddata(new datapoint(graphxtime, curgyroz), true, max_points_displayed); } } @override public void onaccuracychanged(sensor sensor, int accuracy) { //safe not implement } }
i find across 3 fragments repeating lot of graph generation code in onresume
wanted create graphhelper class can instantiate graph creation, benefit of having change code in 1 place if wanted alter of graph. however, new java having trouble wrapping head around creating new class.
attempted solution:
i have managed come following class in attempt solve problem:
public class graphhelper { private final graphview graph; private final linegraphseries<datapoint> xseries; private final linegraphseries<datapoint> yseries; private final linegraphseries<datapoint> zseries; public graphhelper(graphview graph, linegraphseries<datapoint> xseries, linegraphseries<datapoint> yseries, linegraphseries<datapoint> zseries, short maxdisplayed){ this.graph = graph; this.xseries = xseries; this.yseries = yseries; this.zseries = zseries; graph.getlegendrenderer().setvisible(true); graph.getlegendrenderer().setfixedposition(0, 0); graph.getgridlabelrenderer().sethighlightzerolines(false); xseries = new linegraphseries<datapoint>(); yseries = new linegraphseries<datapoint>(); zseries = new linegraphseries<datapoint>(); xseries.settitle("x"); yseries.settitle("y"); zseries.settitle("z"); xseries.setcolor(color.red); yseries.setcolor(color.green); zseries.setcolor(color.blue); graph.addseries(xseries); graph.addseries(yseries); graph.addseries(zseries); graph.getviewport().setyaxisboundsmanual(true); graph.getviewport().setminy(-10); graph.getviewport().setmaxy(10); graph.getviewport().setxaxisboundsmanual(true); graph.getviewport().setminx(0); graph.getviewport().setmaxx(maxdisplayed); } }
and have changed fragment onresume
(everything else same):
@override public void onresume() { super.onresume(); sensormanager.registerlistener(this, gyroscope, sensormanager.sensor_delay_fastest); //create graph graphview gyrograph = (graphview) getview().findviewbyid(r.id.gyrograph); new graphhelper(gyrograph, gyroxseries, gyroyseries, gyrozseries, max_points_displayed); }
problem #1:
i getting following error whenever try view graph fragment:
java.lang.nullpointerexception: attempt invoke virtual method 'void com.jjoe64.graphview.series.linegraphseries.appenddata(com.jjoe64.graphview.series.datapointinterface, boolean, int)' on null object reference
this referring onsensorchanged
method i'm trying append data series. doesn't seem know gyroxseries
because i'm adding graph within helper.
problem #2:
currently i'm declaring gyroxseries
in main fragment class, top of helper class, , creating new linegraphseries
object in helpers constructor. there way reduce repetition of code?
edit
in response comments below, made following changes , new graphhelper class looks this:
public class graphhelper { private final graphview graph; private final linegraphseries<datapoint> xseries; private final linegraphseries<datapoint> yseries; private final linegraphseries<datapoint> zseries; public graphhelper(graphview graph, linegraphseries<datapoint> xseries, linegraphseries<datapoint> yseries, linegraphseries<datapoint> zseries, short maxdisplayed){ this.graph = graph; this.xseries = xseries; this.yseries = yseries; this.zseries = zseries; graph.getlegendrenderer().setvisible(true); graph.getlegendrenderer().setfixedposition(0, 0); graph.getgridlabelrenderer().sethighlightzerolines(false); xseries.settitle("x"); yseries.settitle("y"); zseries.settitle("z"); xseries.setcolor(color.red); yseries.setcolor(color.green); zseries.setcolor(color.blue); graph.addseries(xseries); graph.addseries(yseries); graph.addseries(zseries); graph.getviewport().setyaxisboundsmanual(true); graph.getviewport().setminy(-10); graph.getviewport().setmaxy(10); graph.getviewport().setxaxisboundsmanual(true); graph.getviewport().setminx(0); graph.getviewport().setmaxx(maxdisplayed); } }
the gyroscope fragment same original, change onresume
made above
which results in following error:
fatal exception: main process: net.binarysea.sensorload, pid: 25997 java.lang.nullpointerexception: attempt invoke virtual method 'void com.jjoe64.graphview.series.linegraphseries.settitle(java.lang.string)' on null object reference @ net.binarysea.sensorload.graphhelper.(graphhelper.java:30) @ net.binarysea.sensorload.gyroscopefragment.onresume(gyroscopefragment.java:73) @ android.support.v4.app.fragment.performresume(fragment.java:2005) @ android.support.v4.app.fragmentmanagerimpl.movetostate(fragmentmanager.java:1108) @ android.support.v4.app.fragmentmanagerimpl.movetostate(fragmentmanager.java:1248) @ android.support.v4.app.backstackrecord.run(backstackrecord.java:738) @ android.support.v4.app.fragmentmanagerimpl.execpendingactions(fragmentmanager.java:1613) @ android.support.v4.app.fragmentmanagerimpl$1.run(fragmentmanager.java:517) @ android.os.handler.handlecallback(handler.java:739) @ android.os.handler.dispatchmessage(handler.java:95) @ android.os.looper.loop(looper.java:148) @ android.app.activitythread.main(activitythread.java:5417) @ java.lang.reflect.method.invoke(native method) @ com.android.internal.os.zygoteinit$methodandargscaller.run(zygoteinit.java:726) @ com.android.internal.os.zygoteinit.main(zygoteinit.java:616)
change graph helper class this.
public class graphhelper { public graphhelper(graphview graph, linegraphseries<datapoint> xseries, linegraphseries<datapoint> yseries, linegraphseries<datapoint> zseries, short maxdisplayed){ graph.getlegendrenderer().setvisible(true); graph.getlegendrenderer().setfixedposition(0, 0); graph.getgridlabelrenderer().sethighlightzerolines(false); xseries.settitle("x"); yseries.settitle("y"); zseries.settitle("z"); xseries.setcolor(color.red); yseries.setcolor(color.green); zseries.setcolor(color.blue); graph.addseries(xseries); graph.addseries(yseries); graph.addseries(zseries); graph.getviewport().setyaxisboundsmanual(true); graph.getviewport().setminy(-10); graph.getviewport().setmaxy(10); graph.getviewport().setxaxisboundsmanual(true); graph.getviewport().setminx(0); graph.getviewport().setmaxx(maxdisplayed); } }
call this:
@override public void onresume() { super.onresume(); sensormanager.registerlistener(this, gyroscope, sensormanager.sensor_delay_fastest); //create graph graphview gyrograph = (graphview) getview().findviewbyid(r.id.gyrograph); gyroxseries = new linegraphseries<datapoint>(); gyroyseries = new linegraphseries<datapoint>(); gyrozseries = new linegraphseries<datapoint>(); new graphhelper(gyrograph, gyroxseries, gyroyseries, gyrozseries, max_points_displayed); }
also more proper way helper in java:
public class graphhelper { public graphhelper() { } public static void initializegraph(graphview graph, linegraphseries<datapoint> xseries, linegraphseries<datapoint> yseries, linegraphseries<datapoint> zseries, short maxdisplayed){ graph.getlegendrenderer().setvisible(true); graph.getlegendrenderer().setfixedposition(0, 0); graph.getgridlabelrenderer().sethighlightzerolines(false); xseries.settitle("x"); yseries.settitle("y"); zseries.settitle("z"); xseries.setcolor(color.red); yseries.setcolor(color.green); zseries.setcolor(color.blue); graph.addseries(xseries); graph.addseries(yseries); graph.addseries(zseries); graph.getviewport().setyaxisboundsmanual(true); graph.getviewport().setminy(-10); graph.getviewport().setmaxy(10); graph.getviewport().setxaxisboundsmanual(true); graph.getviewport().setminx(0); graph.getviewport().setmaxx(maxdisplayed); } }
this way don't have random object that's waiting garbage collected. call use:
graphhelper.initializegraph(...)
Comments
Post a Comment