java-如何确保我的Android应用不会同时访问文件?
作者:互联网
我正在构建一个健身应用程序,该应用程序不断在设备上记录活动.我需要经常记录日志,但是我也不想不必要地消耗用户的电量,这就是为什么我在考虑将网络呼叫分批处理并在无线电激活后立即一次全部传输的原因.已连接到WiFi或正在充电.
我正在使用基于文件系统的方法来实现这一点.我首先将数据持久保存到文件中-最终我可能会使用Tape from Square来做到这一点-但这里是我遇到的第一个问题.
我不断将新的日志数据写入文件,但是我还需要定期将所有记录的数据发送到我的后端.发生这种情况时,我将删除文件的内容.现在的问题是,如何防止这两个操作同时发生?当然,如果在尝试从文件读取其他进程并尝试删除其内容的同时尝试将日志数据写入文件,则会导致问题.
我正在考虑使用IntentService本质上充当所有这些操作的队列.而且由于-至少我已经读过很多-IntentServices在单个工作线程中按顺序处理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的更多信息.
总结一下:
您真正需要做的就是在扩展GcmTaskService的Service中实现网络调用,以后每当您需要执行这样的网络调用时,您都可以安排一个OneOffTask,其他所有事情都将由您来照顾!
当然,您不需要像我上面一样调用OneOffTask.Builder的每个设置器-我只是这样做是为了向您展示您拥有的所有选项.在大多数情况下,安排任务看起来像这样:
mGcmNetworkManager.schedule(new OneoffTask.Builder()
.setService(MyTaskService.class)
.setTag(TASK_TAG)
.setExecutionWindow(0L, 300L)
.setPersisted(true)
.setExtras(bundle)
.build());
而且,如果您将其放入帮助程序方法中,或者甚至可以为需要执行的所有不同任务创建工厂方法,而不是尝试执行的所有操作,那么只需将其简化为几行代码即可!
顺便说一句:是的,IntentService在单个工作线程中依次处理每个Intent.您可以查看相关的实现here.它实际上非常简单并且非常简单.
标签:multithreading,android-service,java,android,square-tape 来源: https://codeday.me/bug/20191119/2034977.html