2012-09-14 3 views
5

フラストレーションポスト....android CountDownTimer - 最後のonTickが呼び出されていない - 使用するクリーンなソリューションは何ですか?

私はちょうど「CountDownTimer - last onTick not called」という問題に遭遇しました。

問題

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 ouput

あなたはonTickは1963ms millisUntilFinishedで起こっている最後の呼び出しを見ることができるように、その後、次のコールは約2秒後にonFinishedになります。確かにバグの行動。私はまだ多くの記事を見つけましたが、まだ清潔な解決策はありません。 1つはソースコードに含まれていますが、iDontWantThisフィールドを100に設定した場合は動作します。

私は軽微なフィールドで回避策を気にかけませんが、このようなコア機能はまだわかりません。これに対してクリーンな解決策を得るために人々は何をしていますか?

どうもありがとう

マーティン

UPDATE:

、内部ミリ秒の遅延に最後のダニをsurpressesとも蓄積を防ぐことはありませんサムによってCountDownTimerの非常に便利な修正時間の経過と共に各ティックのミリ秒の遅延が見つかりますhere

答えて

8

実際に発生している動作は、 CountdownTimerコード; have a look at the source

handleMessage()の中に残っている時間がその間隔よりも短い場合は、明示的にonTick()を呼び出しず、完了するまで遅延します。

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

+0

アンドロイドとは全く新しいどうもありがとう、と私はhaventは、ステップが実際にそのような場合には、そのソースコードに見えるように作られました。私にそのステップを指摘してくれてありがとう。私はmillisUntilFinished> 0ならonTickを呼び出し、残ったmillisは自分がやりたいことが許せば簡単にチェックできます(実際には6,5,4,3,2を表示するカウントダウンタイマーが必要です)。 、1,0) – dorjeduck

+0

完全性のためだけにブロックにmillisが残っているときにonTickが呼び出されるようにするには、次のようにelseを削除してください------------------- -------------------------------------------} else if(millisLeft dorjeduck

2

欲求不満は、ダニが何をすべきかという誤った期待から来ていると思います。もう1つの答えとして、この動作は意図的なものです。これを処理するもう1つの方法は、単純に小さな間隔を指定することです。たとえば、何らかのカウントダウン・クロックを実装していた場合、間隔を500に変更することに害はありません。秒が変更されたときにのみ作業が行われることが重要な場合は、getSeconds()その値が変化したときにのみその作業を行います。

残りの時間がインターバルよりも少なくても、最後のティックが常に発火するように変更された場合、StackOverflowには「なぜ最後のティックで十分な時間がないのですか? CountdownTimer?「あなたは、それは意図的な行動であると言う理由

+0

あなたは正しく、私は欲求不満の原因となる異なる行動を期待していました。私はAPIのdocuに記載されていない意図された動作に驚いています。特に上記logcatのように、カウントダウンタイマーは実際には "遅い"ですが、指定されたsecondsLeft/intervalsより47 ms遅れて発生します。私がそれを期待していたので、それは47ミリ秒で起こった。あなたがintervallとして4時間を与える場合を想像してください.43msのためにonTickが呼び出されないと予想します。しかし、はい、それは期待の問題です;) – dorjeduck

1

が、私は理解していない、APIは、正確に言う:

『道に沿って間隔で定期的に通知して、将来の時間までのカウントダウンをスケジュール』

new CountDownTimer(30000, 1000) { 

    public void onTick(long millisUntilFinished) { 
     mTextField.setText("seconds remaining: " + millisUntilFinished/1000); 
    } 

    public void onFinish() { 
     mTextField.setText("done!"); 
    } 
}.start(); 

あなたは1000年に30秒までの時間を設定し、countDownInterval場合、APIは通常の言うように、それは正確に30回を解雇しなければならない。 私はそれが意図的な行動が、間違った実装ではないと思う。

ソリューションは、ここでは、サムが提案したものでなければならない:

android CountDownTimer - additional milliseconds delay between ticks

+0

ありがとうJuan - サムのソリューションは、すでに投稿の更新で参照されています。 – dorjeduck

関連する問題