4

特定の時間にタスクを開始したい。そのために、次のように使用runnableしてpostDelayedメソッドを作成します。

private Runnable mLaunchTask = new Runnable() {
        public void run() {

            try {
                MY TASK
            } catch (IllegalStateException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
};

私のコードでは、次のように使用mLunchTaskします。

mHandler = new Handler();
mHandler.postDelayed(mLaunchTask, myDelay*1000); 

次のようにmyDelay計算されます。

s  = DateFormat.format("hh:mm:ss aaa", d.getTime());
cTime = s.toString(); // current Time
ch = Integer.parseInt(cTime.substring(0,2)); // current hour
cm = Integer.parseInt(cTime.substring(3,5)); // current minute
cs = Integer.parseInt(cTime.substring(6,8)); // current second
if (cTime.substring(9,11).equalsIgnoreCase("pm") && (ch<12) ) ch = ch+12; 
myDelay=(desiredHour-ch)*3600+(desiredMinute-cm)*60 - cs;
if (myDelay<0) myDelay = 0;

およびはユーザーが設定しますdesiredHourdesiredMinute期待されるのは、およびおよび 0 秒でMY TASK開始することです。ただし、「MY TASK は数秒遅れて開始されますが、これはランダムに見えます。desiredHourdesiredMinute

上記のコードに基づいて、正確な時間に開始されない理由はありますか?

ありがとう

4

3 に答える 3

6

まず、遅延の計算は正しいのですが、「pm」の検出は他の言語では機能しません。カレンダーを使用して遅延を取得する方がはるかに優れています。

Calendar calendar = Calendar.getInstance();
long currentTimestamp = calendar.getTimeInMillis();
calendar.set(Calendar.HOUR_OF_DAY, desiredHour);
calendar.set(Calendar.MINUTE, desiredMinute);
calendar.set(Calendar.SECOND, 0);
long diffTimestamp = calendar.getTimeInMillis() - currentTimestamp;
long myDelay = (diffTimestamp < 0 ? 0 : diffTimestamp);

これでミリ秒単位の遅延が発生し、ハンドラーを開始できます。

new Handler().postDelayed(mLaunchTask, myDelay);

私のテストでは、次の実行可能なログを希望の時間に遅滞なく記録しました。

private Runnable mLaunchTask = new Runnable() {
    public void run() {
        Calendar calendar = Calendar.getInstance();
        Log.d("test", "started at " 
            + calendar.get(Calendar.HOUR_OF_DAY) + " " 
            + calendar.get(Calendar.MINUTE) + " "
            + calendar.get(Calendar.SECOND)
        );
    }
};

開始されたタスクをロードするのに数秒かかることがありますか?

AlarmManagerは代わりになるでしょうか?

于 2011-07-18T07:35:04.200 に答える
0

ナリバの答えは完全に正しいわけではありません。

ここで見ることができるドキュメントに基づいて 、このクラスは将来タスクを実行するために特別に使用されることがわかります。

「ハンドラには主に 2 つの用途があります。(1)メッセージとランナブルを将来のある時点で実行するようにスケジュールすることと、(2) 自分のスレッドとは異なるスレッドで実行されるアクションをキューに入れることです。」

システムがスリープ モードに入ったときのアプリケーションの動作に関する参照はなく、追加情報を投稿する前にこの問題をテストする必要があります。

于 2012-01-29T18:22:38.487 に答える
0

私の経験とドキュメントを読んだ結果、postDelayed はリアルタイムではなくアップタイムに基づいています。電話機がディープ スリープ状態になると、アップタイムが増加せずにリアルタイムが経過する可能性があります。これは、タスクが希望よりも遅く開始されることを意味します。

Handler は実際には、アクティブなアクティビティで GUI を更新するように設計されているようであり、タスクをはるか先にスケジュールするのではありません。scessor が言ったように、AlarmManager がおそらく最善の策です。

于 2011-10-06T20:00:38.410 に答える