我有时域数据的样本不断更新名为“rollHistory”的LinkedList,然后将其显示在一个图中,如下所示:
if (rollHistory.size() > HISTORY_SIZE) {
rollHistory.removeFirst(); //remove first value
}
rollHistory.addLast(sensorReading); //insert latest value
rollHistorySeries.setModel(rollHistory , SimpleXYSeries.ArrayFormat.Y_VALS_ONLY); //added 06/24/2013
aprHistoryPlot.redraw();
}
“HISTORY_SIZE”是要绘制的数据的最大长度。这段代码工作正常。但是,我真正希望显示的是时域数据的FFT而不是数据本身。为此,我下载了JTransform库。 realForwardFull()函数似乎期望一个双精度数组,所以我尝试将LinkedList(上面称为rollHistory)转换为数组,然后将其传递给realForwardFull()函数。但是rollHistorySeries.setModel命令似乎期望一个LinkedList。所以我尝试将realForwardFull()的输出转换回链表。代码在eclipse中没有显示任何错误,但是当我尝试在手机上运行时它会关闭。
DoubleFFT_1D fftDo = new DoubleFFT_1D(512);
if (rollHistory.size() > HISTORY_SIZE) {
rollHistory.removeFirst();
}
rollHistory.addLast(sensorReading);
Double[] rollHistoryAr = rollHistory.toArray(new Double[0]); // convert rollHistory to array
double[] fft = new double[256 * 2];
System.arraycopy(rollHistoryAr, 0, fft, 0, 256); //copy rollHistoryAr to fft array
fftDo.realForwardFull(fft); //find fft of rollHistory and save to fft
LinkedList rollHistoryFreq = new LinkedList(Arrays.asList(fft)); //convert back to LinkedList
rollHistorySeries.setModel(rollHistoryFreq , SimpleXYSeries.ArrayFormat.Y_VALS_ONLY); //added 06/24/2013
aprHistoryPlot.redraw();
//mGraph.addDataPoint(sensorReading);
}
我尝试用try / catch包装上面代码的一部分,如下所示:
try {
//jTransform Attempt
Double[] rollHistoryAr = rollHistory.toArray(new Double[rollHistory.size()]);
double[] fft = new double[256];
System.arraycopy(rollHistoryAr, 0, fft, 0, 256);
dfft.realForward(fft);
LinkedList rollHistoryFreq = new LinkedList(Arrays.asList(fft));
rollHistorySeries.setModel(rollHistoryFreq, SimpleXYSeries.ArrayFormat.Y_VALS_ONLY);
} catch (Exception e)
{ e.printStackTrace(); }
在这种情况下,应用程序运行时没有“不幸...停止”错误,但图表为空,LogCat显示以下消息:
07-13 16:18:18.509:W / System.err(11288):java.lang.ArrayStoreException:java.lang.Integer不能存储在java.lang.Double类型的数组中[]
07-13 16:18:18.509:W / System.err(11288):at java.util.LinkedList.toArray(LinkedList.java:958)
07-13 16:18:18.509:W / System.err(11288):at com.example.MyActivity $ ArduinoReceiver.onReceive(MyActivity.java:166)
07-13 16:18:18.509:W / System.err(11288):在android.app.LoadedApk $ ReceiverDispatcher $ Args.run(LoadedApk.java:758)
07-13 16:18:18.509:W / System.err(11288):在android.os.Handler.handleCallback(Handler.java:725)
07-13 16:18:18.509:W / System.err(11288):在android.os.Handler.dispatchMessage(Handler.java:92)
07-13 16:18:18.509:W / System.err(11288):在android.os.Looper.loop(Looper.java:137)07-13 16:18:18.509:W / System.err(11288) :在android.app.ActivityThread.main(ActivityThread.java:5293)
07-13 16:18:18.509:W / System.err(11288):at java.lang.reflect.Method.invokeNative(Native Method)07-13 16:18:18.509:W / System.err(11288):在java.lang.reflect.Method.invoke(Method.java:511)
07-13 16:18:18.509:W / System.err(11288):at com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:1102)07-13 16:18:18.509:W / System.err(11288):at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:869)
07-13 16:18:18.509:W / System.err(11288):at dalvik.system.NativeStart.main(Native Method)
有没有人对我做错了什么有任何想法?如有必要,我可以发布更多代码。谢谢!
答案 0 :(得分:2)
当你说代码关闭时,你的意思是什么?它是否无限期冻结并且没有产生堆栈跟踪,或者应用程序是否实际崩溃并产生堆栈跟踪?如果它是前者,你可以在调试模式下运行应用程序并检查它是否在Androidplot库中的某处冻结?如果是后者,你能提供堆栈跟踪吗?
关于上述代码的几点想法: 首先,根据我的记忆,FFT可以是非常密集的操作。也许没有它们的DFT对手那么糟糕,但从CPU /主线程的角度来看仍然非常重要。我无法确定,但看起来你正在主线程上进行所有的FFT处理,这很糟糕。我强烈建议在后台线程上进行这些计算。这有可能解决您的主要问题。
我还注意到你可能会考虑一个完全可选的优化:你使用SimpleXYSeries作为Series实现,你在上面提到它的setModel(...)方法需要一个LinkedList,这不是真的。它能够接受LinkedList,但也会接受任何List。对于需要任意增长和缩减的动态实现,LinkedList是一个很好的通用选择。然而,特定系列实现的性能是它是否与应用程序的数据模型匹配,并避免了昂贵的复制/新操作的需要。鉴于你使用了一个带有double []的FFT库,我认为更有效的设计是围绕double []编写你自己的XYSeries实现,这样数据可以由plot和fft代码共享。要在您的可见情节中获得相同类型的动态滚动效果,您很可能需要将double []实现为ring buffer。 SimpleXYSeries只是一个方便的实现,可以帮助你开始,但它几乎永远不会是最佳的,因为它试图迎合最低的共同点。同样,这是一个完全可选的性能优化,根据您绘制的点数和频率,可能会浪费时间。