gpt4 book ai didi

java - 如何确保我的 Android 应用程序不会同时访问文件?

转载 作者:太空宇宙 更新时间:2023-11-03 13:51:42 26 4
gpt4 key购买 nike

我正在构建一个健身应用程序,它会持续记录设备上的 Activity 。我需要经常记录,但我也不想不必要地耗尽用户的电池,这就是为什么我正在考虑将网络调用批量处理并在 radio 激活后立即传输它们,设备是已连接到 WiFi 或正在充电。

我正在使用基于文件系统的方法来实现它。我首先将数据保存到 File - 最终我可能会使用 Tape from Square这样做 - 但这是我遇到的第一个问题。

我不断将新的日志数据写入文件,但我还需要定期将所有记录的数据发送到我的后端。发生这种情况时,我会删除 File 的内容。现在的问题是如何防止这两个操作同时发生?当然,如果我尝试将日志数据写入 File,同时一些其他进程正在从 File 中读取并尝试删除其内容,这当然会导致问题。

我正在考虑使用 IntentService 本质上充当所有这些操作的队列。并且因为 - 至少我已经阅读了很多 - IntentServices 在单个 worker Thread 中顺序处理 Intent 它不应该有两个这些操作同时发生,对吗?

目前,我想用 GcmNetworkManager 安排一个 PeriodicTask,它将负责将数据发送到服务器。有没有更好的方法来做这一切?

最佳答案

1) 你想多了!

您的方法比实际情况要复杂得多!出于某种原因,其他答案都没有指出这一点,但是 GcmNetworkManager 已经完成了您试图实现的一切!您不需要自己实现任何东西。


2) 实现您想要做的事情的最佳方式。

您似乎没有意识到 GcmNetworkManager 已经通过自动重试等以最省电的方式对调用进行了批处理,它还在设备启动时持久保存任务,并可以确保它们尽快执行电池效率高,是您的应用所必需的。

只要你有数据要保存,就安排一个 OneOffTask,如下所示:

final OneoffTask task = new OneoffTask.Builder()

// The Service which executes the task.
.setService(MyTaskService.class)

// A tag which identifies the task
.setTag(TASK_TAG)

// Sets a time frame for the execution of this task in seconds.
// This specifically means that the task can either be
// executed right now, or must have executed at the lastest in one hour.
.setExecutionWindow(0L, 3600L)

// Task is persisted on the disk, even across boots
.setPersisted(true)

// Unmetered connection required for task
.setRequiredNetwork(Task.NETWORK_STATE_UNMETERED)

// Attach data to the task in the form of a Bundle
.setExtras(dataBundle)

// If you set this to true and this task already exists
// (just depends on the tag set above) then the old task
// will be overwritten with this one.
.setUpdateCurrent(true)

// Sets if this task should only be executed when the device is charging
.setRequiresCharging(false)

.build();
mGcmNetworkManager.schedule(task);

这会做你想做的一切:

  • 任务将持久化在磁盘上
  • 任务将以批处理和省电的方式执行,最好通过 Wifi 执行
  • 您将拥有可配置的自动重试和电池高效退避模式
  • 任务将在您指定的时间窗口内执行。

我建议初学者阅读 this了解有关 GcmNetworkManager 的更多信息。


总结一下:

您真正需要做的就是在扩展 GcmTaskServiceService 中实现您的网络调用,稍后当您需要执行这样的网络调用时,您可以安排一个 OneOffTask其他一切 都将为您处理!

当然,您不需要像我上面那样调用 OneOffTask.Builder 的每个 setter - 我这样做只是为了向您展示您拥有的所有选项。在大多数情况下,安排任务看起来像这样:

mGcmNetworkManager.schedule(new OneoffTask.Builder()
.setService(MyTaskService.class)
.setTag(TASK_TAG)
.setExecutionWindow(0L, 300L)
.setPersisted(true)
.setExtras(bundle)
.build());

如果你把它放在一个辅助方法中,或者更好地为你需要做的所有不同任务创建工厂方法,那么你尝试做的一切都应该归结为几行代码!


顺便说一下:是的,IntentService 在单个工作线程 Thread 中一个接一个地依次处理每个 Intent。可以看看相关实现here .它实际上非常简单明了。

关于java - 如何确保我的 Android 应用程序不会同时访问文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34350673/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com