在我的Android应用程序中,我试图从包含我希望绘制的数据点的文本文件中读取。每个文件中的数据点数预计在24,000到150,000之间。
目前,我已经实现了一个异步任务,它从压缩文本文件中读取数据并将其存储在本地向量中。在完成任务时,将数据点添加到数据集中以便绘制图形。
异步任务的代码实现如下:
class ReadFileService extends AsyncTask<Void, String, Boolean> {
@Override
protected Boolean doInBackground(Void... args) {
Scanner strings = null;
InputStream stream = null;
ZipInputStream zipInput = null;
try {
System.out.println(externalStorageDirectory + Constants.APP_DIRECTORY + recordingName + Constants.ZIP_FILE_EXTENTION);
File file = new File(externalStorageDirectory + Constants.APP_DIRECTORY, recordingName + Constants.ZIP_FILE_EXTENTION);
ZipFile zipFile = new ZipFile(file);
Enumeration<? extends ZipEntry> entries = zipFile.entries();
while (entries.hasMoreElements()) {
ZipEntry zipEntry = entries.nextElement();
stream = zipFile.getInputStream(zipEntry);
strings = new Scanner(stream);
// Extract the value of sampling frequency from header
System.out.println("Extracting value of sampling frequency.");
String regexPattern = "\"ColumnLabels\"";
strings.useDelimiter(regexPattern);
String extracted = strings.next();
Pattern pattern = Pattern.compile("\"SamplingFrequency\": \"(\\d+)\"");
Matcher matcher = pattern.matcher(extracted);
if (matcher.find()) {
samplingFrequency = Integer.parseInt(matcher.group(1));
System.out.println(samplingFrequency);
}
// Locate the end of the header and use tabs as the delimiter
strings.findWithinHorizon(endOfHeader,0);
strings.useDelimiter("\t *");
strings.next();
}
}
catch (FileNotFoundException error) {
System.out.println("@IOERROR: " + error);
return false;
}
catch (IOException error) {
System.out.println("@IOERROR: " + error);
return false;
}
while (strings.hasNext())
{
// Get raw value of data point
double dataPoint = Double.parseDouble(strings.next());
// Convert data point into the proper scale
dataSet.add(SensorDataConverter.scaleEMG(dataPoint));
// Skip the index value if it exists and break from loop if it does not
if (strings.hasNext())
strings.next();
else
break;
}
System.out.println("Closing strings.");
try {
stream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
strings.close();
return true;
}
protected void onProgressUpdate(String...progress) {
//called when the background task makes any progress
}
protected void onPreExecute() {
//called before doInBackground() is started
super.onPreExecute();
// Show Progress Bar Dialog before calling doInBackground method
prgDialog.setTitle("Opening File");
prgDialog.setMessage("Opening " + recordingName + "\nPlease wait...");
prgDialog.show();
}
//called after doInBackground() has finished
protected void onPostExecute(Boolean readFileSuccess) {
// If unable to read from file, print error and generate a random set of sample data
if(!readFileSuccess) {
Random randomGenerator = new Random();
System.out.println("@IOERROR: Unable to read from file. Creating random dataset");
for(int i=0; i<100; i++)
{
dataSet.add(randomGenerator.nextDouble());
}
}
// Create a set of graph data to use with GraphView
exampleSeries1 = new GraphViewSeries(new GraphViewData[] {
});
for (int i=0; i<dataSet.size(); i++) {
double pointX = i;
double pointY = dataSet.get(i);
exampleSeries1.appendData(new GraphViewData(pointX, pointY), true, dataSet.size());
}
// Plot the data points
graphData();
prgDialog.dismiss();
prgDialog = null;
}
}
在保存和加载大约10,000个数据点并且加载大约需要15秒时,这似乎有效。但是,当数据点数量跃升至20,000时,加载时间最多需要45秒。
我的主要问题是:是否有其他方法可以更有效地处理所有这些数据,以最大限度地缩短加载数据所需的时间?例如,是否可以动态绘制数据图表点取决于视口范围?
非常感谢任何帮助和建议。
答案 0 :(得分:0)
您必须重新采样数据以获得较少的数据点。通常情况下,在单个视口中绘制100多个数据点是没有意义的。
并使用手动视口和手动标签宽度/高度来提高性能