5

欲求不満の投稿....

多くの人がここで報告している「CountDownTimer - 最後の onTick が呼び出されなかった」という問題に遭遇しました。

問題を示す簡単なデモ

package com.example.gosh;

import android.app.Activity;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.util.Log;

public class CountDownTimerSucksActivity extends Activity {

int iDontWantThis = 0; // choose 100 and it works yet ...

private static final String TAG = "CountDownTimerSucksActivity";

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    new MyCountDownTimer(10000 + iDontWantThis , 1000).start();
}

class MyCountDownTimer extends CountDownTimer {

    long startSec;

    public MyCountDownTimer(long millisInFuture, long countDownInterval) {
        super(millisInFuture, countDownInterval);
        // TODO Auto-generated constructor stub
        startSec = System.currentTimeMillis() ;
    }

    @Override
    public void onFinish() {
        // TODO Auto-generated method stub
        Log.e(TAG, " onFinish (" + getSeconds() + ")");
    }

    @Override
    public void onTick(long millisUntilFinished) {
        // TODO Auto-generated method stub
        Log.e(TAG, millisUntilFinished + " millisUntilFinished" + " (" + getSeconds() + ")");

    }

    protected long getSeconds() {
        return  (((System.currentTimeMillis() - startSec) / 1000) % 60);

    }

}

}

テスト実行からのlogcat出力...

logcat出力

最後の呼び出し onTick が 1963ms millisUntilFinished で発生していることがわかります。次の呼び出しはほぼ 2 秒後に onFinished です。確かにバギーな振る舞い。これに関する多くの投稿を見つけましたが、まだクリーンなソリューションはありません。iDontWantThis フィールドを 100 に設定すると、ソース コードに含めた 1 つが機能します。

マイナーな分野での回避策は気にしませんが、これはコア機能のようで、まだ修正されていないとは言えません。これに対する明確な解決策を得るために、あなたは何をしていますか?

どうもありがとう

マーティン

アップデート:

内部のミリ秒遅延のために最後のティックを抑圧せず、時間の経過とともに各ティックでのミリ秒遅延の蓄積を防止する Sam による CountDownTimer の非常に便利な変更は、ここにあります。

4

4 に答える 4

8

発生している動作は、実際にはCountdownTimerコードで明示的に定義されています。ソースを見てください

の内部に注意してくださいhandleMessage()。残り時間が間隔よりも短い場合、明示的に呼び出さonTick()れず、完了するまで遅延します。

ただし、 Android フレームワークの実際のタイミング コンポーネントであるCountdownTimerの非常に薄いラッパーであるソースから注意してください。Handler回避策として、このソース (150 行未満) から独自のタイマーを非常に簡単に作成し、この制限を削除して最終的なティック コールバックを取得することができます。

于 2012-09-14T20:09:27.070 に答える
2

欲求不満は、ダニがどうあるべきかについての誤った期待から来ていると思います。他の回答が指摘したように、この動作は意図的なものです。これを処理する別の可能な方法は、より小さな間隔を指定することです。たとえば、ある種のカウントダウンクロックを実装している場合、間隔を500に変更しても問題はありません。秒が変更されたときにのみ作業を行うことが重要な場合は、との結果を保存することでそれを行うこともできますgetSeconds()。その値が変更されたときにのみその作業を行います。

CountdownTimer残り時間が間隔より短くても常に最後のティックを起動するように変更された場合、StackOverflowには「最後のティックに十分な時間がないのはなぜですか?」などの質問がたくさんあるはずですCountdownTimer

于 2012-09-14T20:35:41.487 に答える