-1

私は学士論文に取り組んでいて、問題に遭遇しました。

私が持っているもの:

外部デバイスからのセンサー データを測定するアプリを作成しました。したがって、長期間にわたって実行する必要があります。

MainActivityの場合、ユーザーはボタンを押してService. その中に複数の と をService作成します(センサーごとに 1 つ)。私はそれらを2つの別々のsに保管します。各センサーには、呼び出される頻度を示す独自の期間があります。たとえば、センサー 1 は 10 秒ごとに呼び出され、センサー 2 は 5 分ごとに呼び出されます。これを達成するために私は呼び出しますTimerTimerTaskList

timer.scheduleAtFixedRate(currentTask, 0, period);

が開始されるたびTimerTaskService

このrun()メソッドでは、センサーを呼び出して、その値とタイムスタンプをアプリのデータベースに保存します。

問題は何ですか:

デバイスがオンになっている限り、すべてが完全に正常に機能します。しかし、デバイスがスリープ状態になるとすぐに、おかしな動作を始めます。

例: 10 秒ごとに値を取得するようにスケジュールされたセンサーが 1 つあります。スタートを押して、デバイスを 30 秒間オンのままにします。このようにして、10秒ごとに3つの値を取得します。次に、電源を押して 1 分間スリープ モードにし、再び電源を入れます。私が得たのは(予想どおり)6つの値ですが、タイムスタンプが適合しません。デバイスがオンだった最後のタイムスタンプと最初にスリープ状態になったタイムスタンプの間に 10 秒以上あります。次のいくつかは、run()メソッドが同じ秒内に複数回呼び出されたことを意味する同じタイムスタンプを持っています。デバイスの電源を入れると、すべて正常に戻り、正常に動作します。

これは、スリープ モード中に何かが正しく機能していないことを意味します。と に何か関係があるに違いないTimerTaskと思いTimerます。

さらに重要な情報:

除外できるもの(推測):

  • システム時間を呼び出す方法(試してみましたがSystemClock.elapsedRealtime()、同じ問題です)
  • デバイス(Nexus 7(2013)とS3 Miniでテストしましたが、どちらも失敗しましたが、 Nexus 4では機能しました。つまり、これは正しくスリープしないようですが、それは別の問題だと思います)
  • 外部センサー (テストのためだけに実際のセンサーを呼び出すのではなく、ランダムな値を作成する代わりにシミュレーションを使用するため)
4

1 に答える 1

0

TimerTask と Timer に何か関係があるに違いないと思います。

CPU の電源がオフになると、コードは実行されません。

デバイスが常に電源に接続されてて、UI が常にフォアグラウンドにある場合はandroid:keepScreenOn="true"、その UI にウィジェットを追加して、画面と CPU の電源を入れたままにします。

または、デバイスが常に電源に接続されている場合は、CPU の電源を入れたままにするために独自のものを入手してくださいWakeLock。これにはWAKE_LOCK許可が必要になります。これは本番アプリには適したソリューションではありませんが、ラボでの実験 (つまり、Play ストアで出荷しないもの) には問題ありません。

または、デバイスが電源に接続されない場合は、、、およびを次のいずれかに置き換えます。TimerTimerTaskServiceAlarmManager

これらは、デバイスをスリープ モードから復帰させ、デバイスを再びスリープ状態にする前に、少し作業を行うことができます。

ただし、外部ハードウェアに接続することを実際に計画している場合は、デバイスがスリープ モードから復帰するときにデバイスを外部ハードウェアに再度接続するためのハンドシェイクに時間がかかりすぎる可能性があるため、このアプローチがうまく機能しない可能性があることに注意してください。その場合、WakeLockアプローチを実行できるように、デバイスに常に電力が供給されていることを確認する必要があります。

于 2013-10-12T12:37:41.183 に答える