Forum Coders' city Strona Główna Coders' city
Nasza pasja to programowanie!
 

 PomocPomoc   SzukajSzukaj   UżytkownicyUżytkownicy   GrupyGrupy  RejestracjaRejestracja 
Archiwum starego forum + teoria    RSS & Panel/SideBar
 ProfilProfil   Zaloguj się, by sprawdzić wiadomościZaloguj się, by sprawdzić wiadomości   ZalogujZaloguj 

Potrzebuję szybkiej odpowiedzi na moje pytanie... Zasady

[Android] CountDownTimer - błędnie odlicza koniec



 
Odpowiedz do tematu    Forum Coders' city Strona Główna -> Java
Zobacz poprzedni temat :: Zobacz następny temat  
Autor Wiadomość
dizel1985



Dołączył: 03 Maj 2006
Posty: 9

PostWysłany: Nie Lis 29, 2015 7:01 pm  OP    Temat postu: [Android] CountDownTimer - błędnie odlicza koniec Odpowiedz z cytatem Pisownia

Witam,
Mam problem z mogło by się wydawać błahą rzeczą jaką jest prosty timer który odlicza mi czas na telefonie. Wszystko działa super do momentu kiedy odliczanie nie dojdzie do końca. Gdy tak się stanie, na wyświetlaczu zamiast zobaczyć 00:00:00 widzę 00:00:01. Odliczać powinno do 0 a nie zatrzymywać się na 1 sekundzie. Może Wy mi pomożecie i podpowiecie gdzie jest błąd bo mi już kończyły się pomysły. Poniżej kod.

Kod:

import android.annotation.SuppressLint;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import java.util.concurrent.TimeUnit;

public class myClass extends AppCompatActivity {
    public static Button start;
    private static TextView timer;
    MediaPlayer finish;
    Counter time = new Counter(10000, 1000);

    @SuppressLint("SetTextI18n")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_singles_carrom);
        start = (Button) findViewById(R.id.start);
        timer = (TextView) findViewById(R.id.timer);
        timer.setText("00:00:10");
        finish = MediaPlayer.create(this,R.raw.gong);


        start.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                try {
                    time.start();
                } catch (NumberFormatException e) {
                    e.printStackTrace();
                }

            }
        });

    }
    public class Counter extends CountDownTimer {
        public Counter(long miliseconds, long interval) {
            super(miliseconds, interval);

        }

        @Override
        public void onTick(long millisUntilFinished) {
            String hms = String.format("%02d:%02d:%02d", TimeUnit.MILLISECONDS.toHours(millisUntilFinished),
                    TimeUnit.MILLISECONDS.toMinutes(millisUntilFinished) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(millisUntilFinished)),
                    TimeUnit.MILLISECONDS.toSeconds(millisUntilFinished) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millisUntilFinished)));
            timer.setText(hms);

        }

        @Override
        public void onFinish() {
            finish.start();
        }

    }
}



Zrobiłem sobie wydruk odliczania i ewidentnie kończy na sekundzie przed końcem, zobaczcie:
11-29 18:15:28.103 30180-30180/com.example.ccc I/System.out: 00:00:10
11-29 18:15:29.106 30180-30180/com.example.ccc I/System.out: 00:00:08
11-29 18:15:30.116 30180-30180/com.example.ccc I/System.out: 00:00:07
11-29 18:15:31.126 30180-30180/com.example.ccc I/System.out: 00:00:06
11-29 18:15:32.136 30180-30180/com.example.ccc I/System.out: 00:00:05
11-29 18:15:33.146 30180-30180/com.example.ccc I/System.out: 00:00:04
11-29 18:15:34.156 30180-30180/com.example.ccc I/System.out: 00:00:03
11-29 18:15:35.166 30180-30180/com.example.ccc I/System.out: 00:00:02
11-29 18:15:36.176 30180-30180/com.example.ccc I/System.out: 00:00:01
Powrót do góry
Zobacz profil autora Wyślij prywatną wiadomość
marcin_an
Site Admin


Dołączył: 26 Maj 2005
Posty: 18736

PostWysłany: Nie Lis 29, 2015 7:41 pm      Temat postu: Odpowiedz z cytatem Pisownia

Czas "00:00:00" nie jest wyświetlany zapewne dlatego, że nie wyświetlasz czasu "00:00:00" w momencie zakończenia.

Poza tym:
  1. Czemu część pól jest dostępna spoza klasy? W szczególności czemu start jest publiczny?!
  2. Ile razy chcesz umożliwić użytkownikowi wywołanie time.start()?
  3. Linia 30: prawdopodobny wyciek zasobów. Wątpię, żeby obiekt tej klasy faktycznie miał być trzymany przez cały czas życia obietu start.
Powrót do góry
Zobacz profil autora Wyślij prywatną wiadomość
dizel1985



Dołączył: 03 Maj 2006
Posty: 9

PostWysłany: Nie Lis 29, 2015 10:38 pm  OP    Temat postu: Odpowiedz z cytatem Pisownia

Widzisz Kolego, ja aż tak dużego doświadczenia w programowaniu nie mam. Można powiedzieć że javy dopiero się uczę a jak wiadomo najłatwiej uczy się na własnych błędach bo nie myli się tylko ten co nic nie robi. Ale do rzeczy. Bo zainteresowałeś mnie tym wyciekiem. On jest a raczej był bo jak robiłem
Kod:
timer.start();
to emulator po zakończeniu odliczania wyświetlał mi błąd że możliwy wyciek ale w chwili gdy ubrałem to w wyjątek to błąd zniknął. Rozumiem że nie jest to prawidłowe rozwiązanie? Czy prawidłowym rozwiązaniem było by zadeklarowanie tego OnClickListenera w klasie Counter i tam go wywoływać? Bo ja faktycznie wywołuję go w klasie nadrzędnej. Gdybyś miał chwilkę aby mi to troszeczkę wytłumaczyć to byłym Ci ogromnie wdzięczny. Na pewno zgłębię temat.

A co do tego nie pokazywania 00:00:00. Muszę go jakoś specjalnie wyświetlić? Mówiąc szczerze wydawało mi się że odliczanie następuje od określonej wartości właśnie do 00 i wyświetlanie tego czasu jest jakby domyślnie i nie trzeba go jakoś specjalnie obsługiwać.
Powrót do góry
Zobacz profil autora Wyślij prywatną wiadomość
marcin_an
Site Admin


Dołączył: 26 Maj 2005
Posty: 18736

PostWysłany: Nie Lis 29, 2015 11:05 pm      Temat postu: Odpowiedz z cytatem Pisownia

dizel1985 napisał:
to emulator po zakończeniu odliczania wyświetlał mi błąd że możliwy wyciek ale w chwili gdy ubrałem to w wyjątek to błąd zniknął. (...)
Więc może należało się zastanowić, czemu jest błąd, a nie na chama uciszać narzędzie, które próbuje cię uchronić? Ignorując błędy i zatykając gębę kompilatorowi/emulatorowi/lintowi/czemukolwiek na dłuższą metę tylko psujesz sobie aplikację.

Aczkolwiek akurat nie wiem, co emulator mógł zgłosić, więc na ten temat nie mogę się wypowiedzieć. Natomiast wyciek, o którym mówię, jest typowym wyciekiem spowodowanym zależnością cykliczną w obserwatorze. Obiekt obserwowany trzyma mocną referencję do obserwatora, obserwator trzyma mocną referencję do obiektu obserwowanego. Sytuacja notorycznie się powtarzająca ze względu na bezrefleksyjne wykorzystanie anonimowych klas i niestatycznych klas wewnętrznych. Przy tak małym programie zapewne nie będzie to miało praktycznego znaczenia, bo masz najwyżej kilka takich obiektów przez cały czas pracy programu i zapewne i tak czas ich życia jest tak samo długi. Ale przy bardziej złożonych aplikacjach i ciekawszysch scenariuszach wreszcie coś zacznie się sypać.

Rozwiązaniem jest użycie WeakReference lub SoftReference. Tutaj jeszcze ujdzie bez, ale zainteresuj tymi klasami (i ich wykorzystaniem w obserwatorach), jak również przyjrzyj się klasom anonimowym i klasom wewnętrznym.

dizel1985 napisał:
A co do tego nie pokazywania 00:00:00. Muszę go jakoś specjalnie wyświetlić? Mówiąc szczerze wydawało mi się że odliczanie następuje od określonej wartości właśnie do 00
Przecież dochodzi do zera. Chyba że onFinish nie jest wywoływane, ale o niczym takim do tej porty nie wspomniałeś. Skoro wykonuje się onFinish, to licznik doszedł do zera. A w onFinish nie widzę niczego, co mogłoby odpowiadać za ustawienie tekstu na "00:00:00".

dizel1985 napisał:
i wyświetlanie tego czasu jest jakby domyślnie i nie trzeba go jakoś specjalnie obsługiwać.
Domyślnie? Znaczy się zakładasz, że developerzy Androida umieścili w bibliotece kod dla twojego pojedynczego programu i w twoim (i tylko twoim) programie coś się magicznie samo ustawi? :D

Przecież chyba logicznym jest, że klasa CountDownTimer nie ma bladego pojęcia o twojej aplikacji i nie ustawi tekstu na "00:00:00", jeżeli nie napiszesz kodu, który miałby to robić. Prawda?
Powrót do góry
Zobacz profil autora Wyślij prywatną wiadomość
dizel1985



Dołączył: 03 Maj 2006
Posty: 9

PostWysłany: Nie Lis 29, 2015 11:16 pm  OP    Temat postu: Odpowiedz z cytatem Pisownia

Jeżeli chodzi o błąd który zwracał mi kompilator to wyglądał on tak:

11-29 11:29:35.980 1689-1699/com.google.process.gapps E/StrictMode: A resource was acquired at attached stack trace but never released. See java.io.Closeable for information on avoiding resource leaks.
11-29 11:29:35.980 1689-1699/com.google.process.gapps E/StrictMode: java.lang.Throwable: Explicit termination method 'end' not called
11-29 11:29:35.980 1689-1699/com.google.process.gapps E/StrictMode: at dalvik.system.CloseGuard.open(CloseGuard.java:180)
11-29 11:29:35.980 1689-1699/com.google.process.gapps E/StrictMode: at java.util.zip.Inflater.(Inflater.java:82)
11-29 11:29:35.980 1689-1699/com.google.process.gapps E/StrictMode: at com.android.okhttp.okio.GzipSource.(GzipSource.java:62)
11-29 11:29:35.980 1689-1699/com.google.process.gapps E/StrictMode: at com.android.okhttp.internal.http.HttpEngine.unzip(HttpEngine.java:645)
11-29 11:29:35.980 1689-1699/com.google.process.gapps E/StrictMode: at com.android.okhttp.internal.http.HttpEngine.readResponse(HttpEngine.java:827)
11-29 11:29:35.980 1689-1699/com.google.process.gapps E/StrictMode: at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:439)
11-29 11:29:35.980 1689-1699/com.google.process.gapps E/StrictMode: at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:384)
11-29 11:29:35.980 1689-1699/com.google.process.gapps E/StrictMode: at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponseCode(HttpURLConnectionImpl.java:497)
11-29 11:29:35.980 1689-1699/com.google.process.gapps E/StrictMode: at com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.getResponseCode(DelegatingHttpsURLConnection.java:105)
11-29 11:29:35.980 1689-1699/com.google.process.gapps E/StrictMode: at com.android.okhttp.internal.huc.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java)
11-29 11:29:35.980 1689-1699/com.google.process.gapps E/StrictMode: at com.google.android.gms.http.GoogleHttpClient.a(SourceFile:811)
11-29 11:29:35.980 1689-1699/com.google.process.gapps E/StrictMode: at com.google.android.gms.http.GoogleHttpClient.a(SourceFile:776)
11-29 11:29:35.980 1689-1699/com.google.process.gapps E/StrictMode: at com.google.android.gms.http.GoogleHttpClient.execute(SourceFile:676)
11-29 11:29:35.980 1689-1699/com.google.process.gapps E/StrictMode: at com.google.android.gms.http.GoogleHttpClient.execute(SourceFile:660)
11-29 11:29:35.980 1689-1699/com.google.process.gapps E/StrictMode: at com.google.android.gms.auth.be.j.a(SourceFile:220)
11-29 11:29:35.980 1689-1699/com.google.process.gapps E/StrictMode: at com.google.android.gms.auth.be.appcert.a.a(SourceFile:263)
11-29 11:29:35.980 1689-1699/com.google.process.gapps E/StrictMode: at com.google.android.gms.auth.be.appcert.a.a(SourceFile:132)
11-29 11:29:35.980 1689-1699/com.google.process.gapps E/StrictMode: at com.google.android.gms.auth.be.appcert.b.a(SourceFile:43)
11-29 11:29:35.980 1689-1699/com.google.process.gapps E/StrictMode: at com.google.android.gms.auth.b.b.a(SourceFile:62)
11-29 11:29:35.980 1689-1699/com.google.process.gapps E/StrictMode: at com.google.android.gms.auth.b.a.a(SourceFile:120)
11-29 11:29:35.980 1689-1699/com.google.process.gapps E/StrictMode: at com.google.android.gms.auth.b.a.a(SourceFile:61)
11-29 11:29:35.980 1689-1699/com.google.process.gapps E/StrictMode: at com.google.android.gms.auth.be.cron.AuthCronService.a(SourceFile:44)
11-29 11:29:35.980 1689-1699/com.google.process.gapps E/StrictMode: at com.google.android.gms.gcm.al.run(SourceFile:135)


Rozwiązanie o którym piszę aby to ubrać w wyjątek znalazłem na forum stack overflow ale jak widać z tego co piszesz, nie jest ono właściwe.[/list]
Powrót do góry
Zobacz profil autora Wyślij prywatną wiadomość
marcin_an
Site Admin


Dołączył: 26 Maj 2005
Posty: 18736

PostWysłany: Nie Lis 29, 2015 11:21 pm      Temat postu: Odpowiedz z cytatem Pisownia

dizel1985 napisał:
Jeżeli chodzi o błąd który zwracał mi kompilator to wyglądał on tak: (...)
Na oko nie ma on nic wspólnego z tym kodem.

dizel1985 napisał:
Rozwiązanie o którym piszę aby to ubrać w wyjątek znalazłem na forum stack overflow
... i akurat to jest dobre, wysokiej jakości źródło informacji. Polecam.

dizel1985 napisał:
ale jak widać z tego co piszesz, nie jest ono właściwe.
Zależy, co rozumiesz przez "niewłaściwe". To, że trafił się kod gorszej jakości nie oznacza, że nie nadaje się do pokazania sposobu pracy z danym narzędziem. Jest różnica pomiędzy "pokazanie" a "użycie w praktyce". Do pokazania, jak działa CountDownTimerer wg mnie całkowicie wystarczy.
Powrót do góry
Zobacz profil autora Wyślij prywatną wiadomość
Wyświetl posty z ostatnich:   
Odpowiedz do tematu    Forum Coders' city Strona Główna -> Java Wszystkie czasy w strefie CET (Europa)

Strona 1 z 1

 
Skocz do:  
Możesz pisać nowe tematy
Możesz odpowiadać w tematach
Nie możesz zmieniać swoich postów
Nie możesz usuwać swoich postów
Nie możesz głosować w ankietach
Możesz dodawać załączniki na tym forum
Możesz pobierać pliki z tego forum




Debug: strone wygenerowano w 0.04428 sekund, zapytan = 11
contact

| Darmowe programy i porady Jelcyna | Tansze zakupy w Helionie | MS Office Blog |