我正在努力实现Xamarin Timer,我希望有人能解释一下我所看到的某些行为。
我的应用程序有一个正在运行的后台服务,该服务从广播接收器ActionBootComplete开始运行。下面的相关代码。
{Android.App.Application.Context.StartService( new Intent( Android.App.Application.Context, typeof( UDPService ) ) ); }
{Android.App.Application.Context.BindService( udpServiceIntent, udpServiceConnection, Bind.AutoCreate );}
在我的主要活动中,我有一个计时器,它实际上是一个运行状况检查计时器,它向我们的服务发送在线消息。计时器间隔可以自定义,默认值为事件15秒。
/// <summary>
/// Health Check Timer
/// </summary>
System.Timers.Timer m_healthCheckTimer;
在OnCreate方法中,按照以下步骤初始化并启动计时器:-
m_healthCheckTimer = new System.Timers.Timer(m_healthPingInterval * 1000);
m_healthCheckTimer.Elapsed += new System.Timers.ElapsedEventHandler(m_healthCheck_Elapsed);
m_healthCheckTimer.Start();
当计时器过去时,我会触发以下代码,其中一些代码仅用于调试:-
void m_healthCheck_Elapsed(object sender, System.Timers.ElapsedEventArgs e) {
try {
LogFile.WriteInputLog(string.Format("Health Check Time Elapsed - Count {0}", m_healthCounter), "Manager");
m_healthCounter++;
var nextValidPingString = string.Format("{0:hh:mm:ss}", DateTime.Now.AddSeconds( m_healthPingInterval ) ) ;
HealthCheckin(string.Format("{0} - Next Send Time {1}", "Main Activity Update Timer", nextValidPingString));
} catch { }
}
基本上,我看到的是计时器在一段时间内可以正常工作,可能是几个小时,可能是几天,然后我注意到计时器会多次触发。在日志文件中,我将看到2个以上的计数器实例分别增加。因此,运行状况检查100/101/102并与日志记录混在一起可能就是运行状况检查200/201/202。
我的假设是,当应用程序进入后台然后进入前台时,正在重新创建我的主活动,这将创建计时器的第二个实例。
我认为最好的方法是将Timer移到后台服务,但是据我所知,我想知道在当前情况下可以做什么。
我似乎找不到一个可以覆盖的事件,该事件告诉我我的Main Activity正在“重新创建”,因此我可以停止原来的Timer或方法,以便在处置Main Activity时执行相同的操作清理。
预先感谢
丹尼尔。
答案 0 :(得分:0)
您的假设听起来很正确,如果是这种情况,那么您需要使用OnDestroy
方法停止计时器,可以将其放在那里听起来最合适:
m_healthCounter.Dispose();
答案 1 :(得分:0)
根据Android life cycle,除非程序被杀死,否则它将仅在OnCreate方法中执行一次。
第二,在程序的OnDestroy方法中,计时器被清除。
protected override void OnDestroy()
{
base.OnDestroy();
if (null != m_healthCheckTimer)
{
m_healthCheckTimer.Dispose();
}
}
最后,在OnCreate中创建计时器时,请确定是否有计时器 已经存在,然后创建它。
if (null == m_healthCheckTimer){
m_healthCheckTimer = new System.Timers.Timer(m_healthPingInterval * 1000);
m_healthCheckTimer.Elapsed += new System.Timers.ElapsedEventHandler(m_healthCheck_Elapsed);
m_healthCheckTimer.Start();
}