日記#311#312

#311 6月6日

今日は様々な検証よりなぜ2回起動してしまうのかについての仮説を立てることができた。
最大のきっかけはアプリを起動したままでアラームのタイムスタンプを確認していた時だった。
この時はContext(主要処理管轄元のイメージ)がUnityPlayerのアラームとContextがサービスのアラームが並走しているのではないかという仮説を解消する検証中であった。
今まではバックグラウンド処理(アプリを終了しても処理される版)が有効になっているかを確認するために毎回アプリを終了させていたが、今回はアプリを起動したままだと2回処理は起きないだろうと踏んで起動したままにした。
そうしたら、ログが逆に止まらなくなった。
ビックリした。
とりあえず、3周分位のログを取得して見てみると、アラームのセットを行った瞬間に次のアラームが起動してしまっていた。

赤点を付けた部分のログがその1つ上の終了を知らせるログよりも前の時間になっている

ここでようやく気づいた。
計算に高度な正確さを求められていることに。
ここで、今まで2回以上もアラームが起動してしまっていたのはアラームの設定に曖昧さ(隙)があったからだという仮説が生じた。

#312 6月7日

今日は仮説の検証を行った。
結果は、仮説通りだった。

1回目
21時12分に起動するように設定したため急いでいたが、1回だけ起動
2回目
21時17分に起動するように設定した
Context_sはアプリを終了したことが"分かる"ログ

2回しか試していないが、成功したと言える。
言いたいだけなら曖昧さの回避に成功したということ。

今回、この曖昧さを回避できたのはアラーム設定を詳細に正確に行ったからだ。

まず、今回の成功例を挙げる。

AndroidStudio上での日付計算はミリ秒(1/1000 秒)で行われている。
そのため、アラームでセットしたい時間をミリ秒まで設定した。
上から時間、分、秒、ミリ秒となっており、条件分岐でアラームでセットした時間が現在時刻よりも小さい場合は1日分の時間(24*60*60*1000)を追加するようにしている。
このように設定することで、ミリ秒の曖昧さも許すことなくアラームをセットすることができる。
これにどういった意味があるかは失敗例から見てみる。

今までの失敗例はこちら。
これは1時10分でアラームをセットした失敗例だ。
この時はアラームで動作させたい処理が2周してしまった。

1周目
2周目

プログラム的にはこんな状態。

成功例から秒とミリ秒の設定が抜けている。
これによって何が起きたかをログと照らし合わせて考えると、

  1. アラームのセットは1時10分<任意>秒<任意>ミリ秒になる

  2. 条件分岐の条件が、”(アラームのセット時間)が(現在時刻)未満の時”になる

  3. 2.の条件下で比べられる現在の時間は1時10分までになる

  4. 2.と3.の条件によって秒やミリ秒がどんな値でも2.の条件は満たされなくなる
    つまり、現在時刻が1時11分になるまで2.の条件が満たされることがなくなる

  5. この間に”アラームが過ぎてしまった状態なので、アラームで動作させたい処理が起動してしまう”現象が起きてしまう

ということが分かる。

よって、1日1回の歩数取得は正確に詳細にすることで2重に3重で記録してしまう現象を回避することができる。
今回は目覚まし時計のようなアラームのキャンセル部分がないため、この正確さが求められると考えている。

1ヶ月以上の時間をかけて、ようやく”1日1回0時0分0秒0ミリ秒に日付と歩数をファイルに記録する”というすごく単純なことが完了した。

今日はこれでおしまいにする。

この記事が気に入ったらサポートをしてみませんか?