Room Database (基本的に SQLite のラッパー) からデータを取得して、そのデータのチェックを行う必要があるアプリがあります。
この非同期呼び出しを毎分トリガーする Handler を使用して実装しました。ハンドラは mainThread に登録されていますが、タスクが呼び出されると、新しいスレッドをディスパッチしてこのタスクをバックグラウンドで実行します。
私の問題は、アプリケーションがフォアグラウンドにないときにこの操作を行う必要がないことです。理想的には、アプリがフォアグラウンドに戻ったときにハンドラーがタスクを起動し、そのタスクが終了した後、1 分以内に次の呼び出しをスケジュールする必要があります。
しかし、ホームボタンをクリックしてアプリを終了し、他のアプリを開くと、この操作が行われたことについてアプリがログを作成しているのが表示されます。
私の問題は、これが 6 時間または 7 時間実行されると、ユーザーの電話にバッテリーの影響が残るのではないかと心配していることです。アプリで行われたウェイクロックはありません。
編集: このクラスを使用する 3 つのアクティビティがあり、これ (BackcgroundExecutor) はシングルトンの内部クラスです。それを1つのライフサイクルに接続すると、3つすべてのライフサイクルに応じて適切に機能させる必要があります。
この問題をどのように修正しますか?
private class BackgroundExecutor implements Runnable {
@Override
public void run() {
Thread temp = new Thread(new Runnable() {
@Override
public void run() {
long time = Calendar.getInstance().getTimeInMillis();
Log.d("DB", time + " inside of Run method");
evaluateTasks();
evaluateComplexTasks();
long nextTime = nextMinute();
handler.postAtTime(new BackgroundExecutor(), nextTime);
}
});
temp.start();
}
void evaluateTasks() {
// Grab tasks
Task[] tasks = dao.primaryDAO().loadTasksForCheck();
LinkedList<Task> tasksToUpdate = new LinkedList<>();
// Evaluate if any of them got data changed
for (Task t: tasks) {
if (t.checkForFieldUpdate()) {
tasksToUpdate.add(t);
}
}
// Re-save those that have
if (tasksToUpdate.size() > 0) {
Task[] temp = new Task[tasksToUpdate.size()];
tasksToUpdate.toArray(temp);
dao.primaryDAO().insertTask(temp);
}
}
void evaluateComplexTasks() {
// Grabs Complex Tasks
ComplexTasks[] complexTasks = dao.primaryDAO().loadComplexTasksForCheck();
LinkedList<ComplexTasks> tasksToUpdate = new LinkedList<>();
// Evaluate if all tasks are completed
for (ComplexTasks t: complexTasks) {
if (t.checkForTaskStatusUpdate()) {
tasksToUpdate.add(t);
}
}
// Re-save those tasks;
if (tasksToUpdate.size() > 0) {
dao.primaryDAO().insertComplexTask((ComplexTasks[]) tasksToUpdate.toArray());
}
}
}