0

私は Xamarin タイマーの実装に苦労しており、誰かが私が見ている動作のいくつかを説明できることを望んでいました.

私のアプリケーションには、実行中のバックグラウンド サービスがあり、ブロードキャスト レシーバーの 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 つ以上のカウンター インスタンスが個別に増加していることがわかります。したがって、Health Check 100 / 101 / 102 とログに混在していると、Health Check 200 / 201 / 202 になる可能性があります。

アプリがバックグラウンドに移行してからフォアグラウンドに移行すると、メイン アクティビティが再作成され、タイマーの 2 番目のインスタンスが作成されると想定しています。

最善の方法はタイマーをバックグラウンド サービスに移動することだと思いますが、私の知る限り、現在のシナリオで何ができるかを知りたいと思います。

メイン アクティビティが「再作成」されていることを示すオーバーライド可能なイベントが見つからないように見えるので、メイン アクティビティが破棄されて同じ種類のクリーンアップを実行するときに、元のタイマーまたはオーバーライドするメソッドを停止できます。 .

前もって感謝します、

ダニエル。

4

2 に答える 2

0

Android のライフ サイクルに従って、プログラムが強制終了されない限り、OnCreate メソッドで 1 回だけ実行されます。

  • まず、プログラムで別のタイマーが作成されているかどうか、またはプログラムがアクティビティを再度開いているように見えるかどうかを確認する必要があります。
  • 次に、プログラムの 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();
     }
    
于 2019-06-18T03:19:25.390 に答える