2012-09-14 6 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 ouput

당신이 onTick이 1963ms millisUntilFinished으로 일어나고있는 마지막 호출을 볼 수 있듯이, 다음 다음 호출은 거의 2 초 후에 onFinished됩니다. 확실하게 버그 투성이의 행동. 나는 이것에 대한 많은 게시물을 아직 찾지 못했다. 하나는 내가 소스 코드에 포함 된 경우, 100으로 iDontWantThis 필드를 설정하면 작동합니다.

사소한 필드에서 해결 방법을 신경 쓰지는 않지만 아직 핵심 기능이 없어서 아직 해결되지 않았다고 생각합니다. 이것에 대한 깨끗한 해결책을 얻기 위해 사람들은 무엇을하고 있습니까?

덕분에 많은

마틴은

UPDATE :

인해 내부 MS 지연에 마지막 틱을 surpresses하지 않는 샘으로 CountDownTimer의 매우 유용한 수정 축적을 방지 시간에 따른 각 틱의 ms 지연 시간은 찾을 수 있습니다. here

답변

8

발생하는 동작은 실제로 CountdownTimer 코드; have a look at the source.

handleMessage()의 내부에 알림 남은 시간이 간격보다 작 으면 명시 적으로 onTick()을 호출하지 않고 완료 될 때까지 지연 만합니다.

소스에서 알 수 있듯이 CountdownTimerHandler의 매우 얇은 래퍼이며 안드로이드 프레임 워크의 실제 타이밍 구성 요소입니다. 이 문제를 해결하기 위해이 소스 (150 줄 미만)에서 직접 자신의 타이머를 만들고이 제한을 제거하여 최종 틱 콜백을 얻을 수 있습니다.

+0

고마워, 안드로이드 아주 새로운 사실 ​​그런 경우 소스 코드를 조사 할 수있는 단계를 만들어를 havent. 저를 가리켜 주셔서 감사합니다. 나는 millisUntilFinished> 0이면 항상 onTick을 호출하고, 나머지 millis는 내가 원하는 것을 허용하는지 쉽게 확인할 수있는 제안 된대로 내 자신의 CountDownTimer를 구현할 것이다 (실제로 나는 6,5,4,3,2를 표시하는 카운트 다운 타이머가 필요하다. , 1,0) – dorjeduck

+0

완전성을 위해 블록에 남은 밀리 초가있을 때마다 onTick이 호출되도록하려면 다음을 제거하십시오. ------------------- -------------------------------------------} else if (millisLeft dorjeduck

2

나는 좌절감이 진드기가 틀림없는 잘못된 기대에서 비롯된 것이라고 생각합니다. 다른 대답이 지적한대로이 동작은 의도적입니다. 이것을 처리 할 수있는 또 다른 방법은 간단히 작은 간격을 지정하는 것입니다. 예를 들어 일종의 카운트 다운 시계를 구현했다면 간격을 500으로 변경하는 것이 좋습니다. 초 작업이 변경 될 때 일부 작업 만 수행하는 것이 중요하다면 getSeconds()의 결과를 저장하여 작업을 수행 할 수도 있습니다 그 가치가 변할 때만 그 일을하는 것입니다.

남은 시간이 간격보다 짧지 만 CountdownTimer이 항상 마지막 틱을 실행하도록 변경된 경우 StackOverflow에 "왜 마지막 틱에서 충분한 시간이 없습니까? CountdownTimer?"

+0

당신은 방금 나는 좌절의 원인이되는 다른 행동을 기대했습니다. 나는 API docu에 언급되지 않은 의도 된 행동에 놀랐다. 위의 logcat처럼 카운트 다운 타이머를 볼 수있다. 실제로는 모든 tick마다 "late"로 주어진 secondsLeft/intervals보다 47ms 늦게 발사된다. 그 47ms 때문에 onTick은 내가 기대했던대로 호출되지 않습니다. 인터뷰로 4 시간을 준 경우를 상상해보십시오. 누가 43 초 때문에 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(); 
30 초에 시간을 설정하면

하고, API 일반 말한대로, 정확히 30 시간을 해고해야 1000에 countDownInterval. 나는 그것이 의도적 인 행동하지만 잘못된 구현하지 생각합니다.

이 솔루션은 샘에 의해 제안 된 것이어야한다 :

android CountDownTimer - additional milliseconds delay between ticks

+0

감사합니다. Juan - Sam의 솔루션은 이미 게시물의 업데이트에서 언급되었습니다. – dorjeduck

관련 문제