取消定时器

3
我在我的日志记录器类中遇到了一个计时器问题。我创建了自己的日志记录器,应该尽可能简单 - 用户只能调用静态log()方法。每次调用log()方法都会导致将日志对象(消息、时间、附加信息)添加到日志列表中。
当用户第一次调用此方法时,记录器还会启动一个新的计时器,每30秒将所有日志保存到文件中。
然而,我不知道在哪里调用timer.cancel()方法。我不想强制用户在他的代码中这样做。是否有必要始终取消计时器?或者只有在用户需要停止时才需要使用此方法?

为什么不使用Android的日志记录机制?http://developer.android.com/reference/android/util/Log.html - mibollma
我需要将我的消息记录到文件中,但是android.util.Log不支持它(如果我错了,请纠正我的观点)。 - mchrobok
2个回答

1
一个关闭挂钩是解决方案。请阅读注意事项和描述这里。还要考虑这个,以获得预先编写的用于Android解决方案的日志文件。

我几天前了解了Microlog,但我想要在新线程中将日志写入文件(不是一个接一个的写,而是同时写入多个)。我不确定,但当我使用Microlog时,它可能会在同一线程中将日志写入文件。 - mchrobok

1

但在这种情况下,您根本不需要关闭挂钩。当VM关闭时,所有线程都将被取消,所有打开的文件都将被关闭,因此不用担心。

我认为您想要避免任务即使应用程序没有执行任何操作也每30秒连续唤醒。我建议稍微改变一下:

每次在日志方法中记录日志时:

  • 存储日志条目
  • 检查是否有等待执行的计时器任务(一个布尔易失性“taskRunning”标志)。如果没有-延迟30秒触发任务,但仅一次(不重复),并将taskRunning标志设置为true。如果标志设置为true-则不执行任何操作。
  • 在计时器任务中:清除“taskRunning”标志,写入到目前为止存储的所有日志,然后...不再触发另一个任务。没必要。每当有人写入日志文件时,它将启动另一个任务,该任务将在30秒后写入日志。

注意。为了避免竞争,您还需要对日志读/写进行一些同步。


谢谢 - 这是一个好的解决方案,我会尝试在我的项目中使用它。但首先,我有一个问题 - 定时器线程会每次(在触发新任务后)都被创建,还是只在启动定时器后创建一次?我猜想只会创建一次,但我想确认一下。 - mchrobok
你是正确的。所有任务都在一个线程中执行,该线程在启动计时器时创建。 - Jarek Potiuk
我在我的项目中使用了你的解决方案,它很有效。但是,有一件事情还不太清楚。如果应用程序以正常方式关闭(或意外关闭),这个线程会被停止和清理吗?还是我需要自己取消它?我可以在onDestroy()方法中取消计时器,但我不想强制用户这样做。其次,如果应用程序在计时器线程保存日志时停止,会怎么样?线程会在工作中途停止还是全部保存? - mchrobok
很高兴听到这个消息。对于线程关闭,情况基本相同 - 当应用程序关闭时,所有线程和打开的文件都会关闭。在Android中,进程(虚拟机)实际上很少关闭 - 通常是当您使用(例如)高级任务杀手、强制关闭异常或没有足够的内存来加载另一个应用程序时才会发生。在这种情况下,应用程序被“强制”终止 - 即进程被终止...线程也会随之而亡。如果恰好在此时线程正在写入 - 它将在工作中间被终止。 - Jarek Potiuk
是的。如果您真的非常想尽最大努力编写所有日志,这就是可行的方式。实际上,您可能需要考虑另一个选项——保持日志文件打开并直接将日志写入其中。向文件写入日志最慢的部分是打开它,如果您将其保持打开状态,就可以直接处理向文件日志写入,而不是将其保存在内存中(特别是如果为其设置一些合理大小的缓冲区)。您最差的情况只会丢失缓冲区(定期进行flush()操作——比每30秒更频繁)。在这种情况下,您可以节省大量的垃圾回收! - Jarek Potiuk
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接