我正在从一个单独的活动中接收加速度计数据,并使用graphview在此活动中对其进行绘图。点图以非常不平滑的方式显示,但是可以正常工作约5秒钟,然后开始挂起并占用大量内存。该代码执行诸如接收和分离数据,记录传入数据的最大值和最小值以及诸如图形和按钮之类的显而易见的UI内容的功能。我正在考虑使用线程,但是是否有最佳实践/简单方法来解决此问题?我在哪里可以使用线程?我的物体还好吗?
public class ShowData extends AppCompatActivity {
private ArrayList<String> xData = new ArrayList<>();
private ArrayList<String> yData = new ArrayList<>();
private ArrayList<String> zData = new ArrayList<>();
double current_max_x = -1000.0;// = -100.0; // set with if size == 1 then current max = array[0]
double current_max_y = -1000.0;
double current_max_z = -1000.0;
double current_min_x = 1000.0;
double current_min_y = 1000.0;
double current_min_z = 1000.0;
TextView Xval;
TextView Yval;
TextView Zval;
final LineGraphSeries<DataPoint> xSeries = new LineGraphSeries<>();
final LineGraphSeries<DataPoint> ySeries = new LineGraphSeries<>();
final LineGraphSeries<DataPoint> zSeries = new LineGraphSeries<>();
// LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(this);
LocalBroadcastManager lbm = null;
IntentFilter filter;
int whereX, whereY, whereZ;
double check;
GraphView graph;
Handler graphHandle = new Handler();
long start = System.currentTimeMillis();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_show_data);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE);
Xval = findViewById(R.id.valueX);
Xval.setTextColor(Color.RED);
Yval = findViewById(R.id.valueY);
Yval.setTextColor(Color.GREEN);
Zval = findViewById(R.id.valueZ);
Zval.setTextColor(Color.BLUE);
graph = (GraphView) findViewById(R.id.graph);
lbm = LocalBroadcastManager.getInstance(this);
filter = new IntentFilter("Data Reception");
xSeries.setColor(Color.RED);
ySeries.setColor(Color.GREEN);
zSeries.setColor(Color.BLUE);
Viewport vp = graph.getViewport();
vp.setXAxisBoundsManual(true);
vp.setMinX(0);
vp.setMaxX(10);
lbm.registerReceiver(xyzData, filter);
}
public BroadcastReceiver xyzData = new BroadcastReceiver() {
@Override
public void onReceive(Context context, final Intent intent) {
//Do the things
String Xdata = intent.getStringExtra("X data");
String Ydata = intent.getStringExtra("Y data");
String Zdata = intent.getStringExtra("Z data");
Xval.setText(Xdata);
Yval.setText(Ydata);
Zval.setText(Zdata);
// All this can be in a separate thread?
try {
if (Xdata.contains("X")) {
char xSet = 'X';
whereX = Xdata.indexOf("X");
try {
Xdata = Xdata.substring(whereX + 3, whereX + 8);
Log.d("Data mani. X", "DataVal: " + Xdata);
currentMax(xSet, Xdata);
currentMin(xSet, Xdata);
} catch (Exception e) {
Log.d("X at end", "" + whereX);
}
}
if (Ydata.contains("Y")) {
whereY = Ydata.indexOf("Y");
char ySet = 'Y';
try {
Ydata = Ydata.substring(whereY + 3, whereY + 8);
Log.d("Data mani. Y", "DataVal: " + Ydata);
currentMax(ySet, Ydata);
currentMin(ySet, Ydata);
} catch (Exception e) {
Log.d("Y at end", "" + whereY);
}
}
if (Zdata.contains("Z")) {
whereZ = Zdata.indexOf("Z");
char zSet = 'Z';
try {
Zdata = Zdata.substring(whereZ + 3, whereZ + 8);
Log.d("Data mani. Z", "DataVal: " + Zdata);
currentMax(zSet, Zdata);
currentMin(zSet, Zdata);
} catch (Exception e) {
Log.d("Z at end", "" + whereZ);
}
}
} catch(Exception e){
e.printStackTrace();
}
//Current implementation requires the lists for data storage/ calculating max values
// if (Xdata != null){
// if(xData.size() < 30) {
// xData.add(Xdata);
// } else {
// xData.remove(0);
// xData.add(Xdata);
// }
//
// }
//Remember youre currently not storing these
// if (Ydata != null){yData.add(Ydata);}
// if (Zdata != null){zData.add(Zdata);}
Log.d("X array", "" + xData);
Log.d("Y array", "" + yData);
Log.d("Z array", "" + zData);
try{
addEntry(Xdata, xSeries);
graph.addSeries(xSeries);
Log.d("X Series Try", "Success");
}catch (Exception e){
e.printStackTrace();
}
try{
addEntry(Ydata, ySeries);
graph.addSeries(ySeries);
Log.d("Y Series Try", "Success");
}catch (Exception e){
e.printStackTrace();
}
try{
addEntry(Zdata, zSeries);
graph.addSeries(zSeries);
Log.d("Z Series Try", "Success");
}catch (Exception e){
e.printStackTrace();
}
}
};
public void addEntry(final String data, final LineGraphSeries Series){
// does there need to be a runnable in a function or can we just do one?
graphHandle.postDelayed(new Runnable() {
@Override
public void run() {
float dataVal = 0;
long current = (System.currentTimeMillis() - start)/1000;
try {
dataVal = Float.parseFloat(data);
Series.appendData(new DataPoint(current ,dataVal), true, 20); // Data point, scroll to end, max data points
Log.i("Time", "" + current);
Log.d("Add Entry", "" + Series.toString());
Log.d("dataVal1", "" + dataVal);
} catch (Exception e) {
e.printStackTrace();
Log.d("STR -> INT", "int dataVal contained string");
Log.d("dataVal2", "" + dataVal);
}
}
}, 100);
}
public void maxVal(View view){
Toast.makeText(ShowData.this, "X: " + String.valueOf(current_max_x) +
", Y: " + String.valueOf(current_max_y) + ", Z: " + String.valueOf(current_max_z), Toast.LENGTH_LONG).show();
}
public void minVal(View view){
Toast.makeText(ShowData.this, "X: " + String.valueOf(current_min_x) +
", Y: " + String.valueOf(current_min_y) + ", Z: " + String.valueOf(current_min_z), Toast.LENGTH_LONG).show();
}
private void currentMax(char val, String data){
check = Double.parseDouble(data);
switch (val){
case 'X':
if (check > current_max_x){
current_max_x = check;
}
case 'Y':
if (check > current_max_y){
current_max_y = check;
}
case 'Z':
if (check > current_max_z){
current_max_z = check;
}
}
}
private void currentMin(char val, String data){
check = Double.parseDouble(data);
switch (val){
case 'X':
if (check < current_min_x){
current_min_x = check;
}
case 'Y':
if (check < current_min_y){
current_min_y = check;
}
case 'Z':
if (check < current_min_z){
current_min_z = check;
}
}
}
}