- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在编写一个应用程序,它将各种传感器(一个传感器的位置)和设备特定的元数据记录到一个文件中,然后将该文件传输到服务器。它不是后台服务 - 应用程序只需要在应用程序处于 Activity 状态时写入和传输文件(无需设置闹钟来唤醒服务)。我想每次 onLocationChanged()
向文件写入一行被调用(尽管位置数据不是唯一被写入的数据) - 或者至少以类似的速率 onLocationChanged()
叫做。 onLocationChanged()
目前被调用一次/秒,但我们最终可能会以更高的速率(可能2-3x/秒)记录数据。这似乎是对内存的大量 I/O。
我目前一切正常(概念证明),但我需要改进用于写入文件的方法。我每次都向文件写入一行 onLocationChanged()
被调用,这可能不明智,并且似乎导致 I/O 堆积。我读过其他类似的问题,涉及各种方法(新线程、警报、计时器任务、处理程序等),但我找不到特定于我想要做的事情的答案。我还考虑过其他方法,例如缓存/缓冲数据并仅以较低频率写入内部存储(每 10 秒?),或者可能写入 SQLite 数据库并稍后导出到文件。我该怎么做才能最好地将文件代码与传感器代码分离(假设这就是我需要做的)并确保及时更新文件?我还需要确保所有数据都写入文件。
更新:我最终使用的解决方案涉及向 StringBuilder 追加一定数量的行(每次调用 onLocationChanged() 一行)。在附加 10 行数据并进行有效缓冲后,我将 StringBuilder 移交给 AsyncTask,数据将在其中写入文件。
最佳答案
在普及定位类(class)中遇到过类似的情况。
这是我们所做的:
文件写入器写入文件部分对我们来说不是问题,因为我们只收集 GPS 位置,而不收集其他传感器数据。对于我们来说,像下面这样的实现就足够了。目前尚不清楚是否必须将数据写入同一个文件,如果不是,那么您应该可以直接使用它。
public class FileOutputWriter {
private static String pathString = "";
private static String sensorString = "";
public static void setPath(Context context, String path) {
pathString = path;
File pathFile = new File(pathString);
pathFile.mkdirs();
}
public static void writeData(String data, String sensor, boolean append) {
File file = new File(pathString + "/" + sensor+ ".log");
long timeStamp = System.currentTimeMillis();
BufferedWriter out = null;
try {
out = new BufferedWriter(new FileWriter(file, append));
out.write(timeStamp + ":" + data);
out.newLine();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
上传者为了将数据上传到服务器,我们创建了一个 LogEntries 提示(将其更改为您自己的数据持有对象或简单的字符串)。
public class DataLogger {
static Vector<LogEntry> log = new Vector<LogEntry>();
public static void addEnty(LogEntry entry) {
Log.d("DEBUG", entry.getStrategy() + " added position to logger " + entry.getLocation());
log.add(entry);
}
public static Vector<LogEntry> getLog() {
return log;
}
public static void clear() {
log.clear();
}
}
请注意,Vector 是线程安全的。
最后我们实现了一个 UploaderThread,负责定期检查 DataLogger 提示并上传添加的条目。
public class UploaderThread extends Thread {
public static LinkedList<String> serverLog = new LinkedList<String>();
Boolean stop = false;
Context c;
public UploaderThread(Context c) {
this.c = c;
}
public void pleaseStop() {
stop = true;
}
@Override
public void run() {
while(!stop) {
try {
if(DataLogger.log.size() > 0 && Device.isOnline(c)) {
while(DataLogger.log.size() > 0) {
LogEntry logEntry = DataLogger.getLog().get(0);
String result = upload(logEntry);
serverLog.add("("+DataLogger.log.size()+")"+"ServerResponse: "+result);
if(result != null && result.equals("OK")) {
DataLogger.getLog().remove(0);
} else {
Thread.sleep(1000);
}
}
} else {
serverLog.add("Queue size = ("+DataLogger.log.size()+") + deviceIsonline: "+Device.isOnline(c));
}
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private String upload(LogEntry entry) {
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://yoururl/commit.php");
try {
// Add your data
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
nameValuePairs.add(new BasicNameValuePair("tracename",sessionName +"-"+ entry.getStrategy().toString()));
nameValuePairs.add(new BasicNameValuePair("latitude", Double.toString(entry.getLocation().getLatitude())));
nameValuePairs.add(new BasicNameValuePair("longitude", Double.toString(entry.getLocation().getLongitude())));
nameValuePairs.add(new BasicNameValuePair("timestamp", Long.toString(entry.getTimestamp())));
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
// Execute HTTP Post Request
HttpResponse response = httpclient.execute(httppost);
if(response != null) {
InputStream in = response.getEntity().getContent();
String responseContent = inputStreamToString(in);
return responseContent;
}
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
private String inputStreamToString(InputStream is) throws IOException {
String line = "";
StringBuilder total = new StringBuilder();
// Wrap a BufferedReader around the InputStream
BufferedReader rd = new BufferedReader(new InputStreamReader(is));
// Read response until the end
while ((line = rd.readLine()) != null) {
total.append(line);
}
// Return full string
return total.toString();
}
}
线程只是在应用程序的第一个 Activity 中启动:
UploaderThread ut;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FileOutputWriter.setPath(this, Environment.getExternalStorageDirectory()
.getAbsolutePath());
ut = new UploaderThread(this);
ut.start();
}
@Override
protected void onDestroy() {
super.onDestroy();
ut.pleaseStop();
}
希望这能让你上路
关于java - Android 定期写入内存上的文件时如何避免 I/O 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20130371/
我是 .NET 编程的新手,目前我正在开发一个计算机健康监控系统,该系统目前处于初级阶段。我将使用 C# 2010 并使用 WMI 查询来查询计算机信息。 在进一步开发应用程序之前,我创建了一个迷你测
我正在考虑开发一个站点,服务器将定期抓取另一个站点,以便为我的数据库中的某些条目收集内容。我的问题如下... 如何让服务器及时执行抓取? 你能让它执行 php 还是你用什么语言来执行抓取? 有什么好的
使用 JobScheduler , 我设置了一个简单的 JobService如下: @TargetApi(21) public class SimpleJobService extends JobSe
我想定期从我的 JavaFX 应用程序执行任务。该任务从远程流中提取数据。 虽然我知道我可以按照下面的建议使用计时器: JavaFX periodic background task 我相信这应该能够
上下文 我们使用多个具有相同工作流程的 git 存储库,涉及两个分支,并且想知道如何最好地将一个提交“同步”到另一个。 简单地说,我们的 git 存储库包含: 长寿枝 两个分支: master(持续开
我正在编写一个需要以高精度和低频率进行后台位置更新的应用程序。解决方案似乎是一个后台 NSTimer 任务,它启动位置管理器的更新,然后立即关闭。之前有人问过这个问题: How do I get a
我有一个包含产品的商业系统。产品被分类并且还具有属性组。 我想同步/更新将来自商务系统的产品转换为在 Orchard 中定义的产品项目的内容类型,以便将数据从商务系统推送到 Orchard 内容项目。
所以我想做的只是按时间间隔更新 Activity 的 View ,比如每秒一次。在这个特定的例子中有几个按钮,我想要改变的只是它们的文本。我在这里阅读了很多解决相同问题的问题,但我似乎比其他人更容易陷
我有一个项目的 recyclerView,(除其他外)包含从 WS 检索的游戏持续时间的时间戳。为了显示比赛的持续时间,我必须获取当前时间戳,做垫子并将其转换为可读格式(例如:5 分钟 5 秒)。只有
这可能是一个愚蠢的问题,但经过几个小时的谷歌搜索后我找不到合适的答案.. 我们有一个在 cloudbees 上运行的业务关键型应用程序。源代码已正确备份,我们希望我们的数据库也有相同的备份。 Clou
我一直在观察我的 PostgreSQL 只读副本显示复制滞后的周期性延迟。延迟似乎会增加到 30-40 分钟,然后自动下降到 0。这与 CPU 利用率 相关,但它远未接近 CPU 限制。 读取流量来自
我已完成 Keepalived + MySQL(master - master)设置。 我将 MASTER 和 BACKUP 的优先级保持不变,因为我不希望它们开始频繁抖动(一次切换 VIP 就足够了
我目前有一个图像,如果本地内容可用,它会被 ping 以仅显示一个 div。 但我认为更好的实现方式是以 30 秒为间隔定期检查 ping,如果图像未成功 ping,则显示 #offline div。
我正在尝试编写一项服务,该服务将每隔 X 分钟尝试获取设备的 GPS 位置,并在后台运行和记录,即使应用程序未处于焦点状态也是如此。 那么,是时候创建服务了。 我创建了一个服务,设置了 locatio
我在这里阅读了很多问题,但无法弄清楚问题是什么。 我正在为 Android 编写现场服务应用程序。在其中一个 Activity (MyActivity.java) 中,我有两个按钮:开始和停止。 当现
假设我有这样的代码: git fetch && git diff origin origin/master --quiet || echo "untracked" 我希望它定期运行。比方说,每秒一次
我想建立与 HTTPS 服务器(例如 google.com)的连接并定期获取新鲜内容。 我编写了简单的 HTTP 客户端: public class AsyncLoader { private
我想定期进行 wifi 扫描(可能每 5 分钟一次)并将结果导出到一个 txt 文件,以便它显示 AP SSID 和 MAC 以及接收到的信号强度。我是 Android 开发的新手,所以我只知道基础知
当手机处于 sleep 模式时,Workmanager 不会向我的服务器发送坐标。异步任务被杀死? 我使用 Workmanager (PeriodicWorkRequest) 每 15 分钟获取一次坐
目标 收集 LogCat 的定期更新并将这些文本 block 保存(附加)到 SD 卡上的文件中 问题 Log 类不提供自特定时间戳以来的更新 可能的解决方案 我的计划是定期运行类似于以下代码:htt
我是一名优秀的程序员,十分优秀!