Autore Topic: Consiglio ottimizzazione per cronometro  (Letto 2119 volte)

Offline andre12

  • Nuovo arrivato
  • *
  • Post: 7
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Motorola Defy
  • Sistema operativo:
    Windows 7
Consiglio ottimizzazione per cronometro
« il: 11 Ottobre 2011, 13:32:57 CEST »
0
Ciao a tutti, questo è il mio primo intervento su questo forum.
Sto sviluppando un cronometro, senza però sfruttare quello già offerto dall'sdk ma riscrivendolo del tutto da capo.
Volevo però chiedere consigli per ottimizzare al massimo la visualizzazione del tempo che scorre tipico dei cronometri su una textview e la risposta alla pressione di un tasto fisico(i pulsanti del volume) per far partire e fermare il cronometro. Chiaramente mi sono messo in ascolto dell'onkeydown, che è l'evento che credo venga scatenato per primo.
Per aggiornare la textview ho creato un thread passandogli un handler con il seguente codice:
Codice (Java): [Seleziona]
final Handler mHandler = new Handler() {
                        @Override
                        public void handleMessage(Message msg) {
                                if (msg.what != 0)
                                        return;
                                // Aggiorno solo se il crono corrente è attivo
                                if (getCurrentChrono().getStatus() == Chrono.RUNNING) {
                                        long currTime = (Long) msg.obj - getCurrentChrono().getStartTime();
                                        getCurrentViewCache().getTxtChrono().setText(ZUtil.cSec2Min(currTime));
                                        getCurrentViewCache().getTxtSessionTime().setText(
                                                        ZUtil.cSec2Min(currTime + getCurrentChrono().getTimesSum()));
                                }
                        }
                };
                // Creazione e start del thread
                chronoThread = new ChronoThread(mHandler);
                chronoThread.start();
E questa è la classe thread che ho definito:
Codice (Java): [Seleziona]
public class ChronoThread extends Thread {

        public Handler mCallerHandler;
        private boolean isRunning = false;

        public ChronoThread(Handler handler) {
                mCallerHandler = handler;
        }

        public synchronized void start() {
                isRunning = true;
                super.start();
        }

        public synchronized void cancel() {
                isRunning = false;
        }

        public void run() {
                while (isRunning) {
                        try {
                                mCallerHandler.obtainMessage(0,new Long(SystemClock.elapsedRealtime()/10)).sendToTarget();
                                Thread.sleep(10);
                        } catch (InterruptedException e) {
                        }
                }
        }
}
Volevo sapere se c'era qualche implementazione migliore, perchè mi pare che ogni tanto si impunti un po sul mio smartphone di test e che soprattutto non risponda istantaneamente alla pressione dei pulsanti fisici.

Grazie

Offline bradipao

  • Moderatore globale
  • Utente storico
  • *****
  • Post: 4043
  • keep it simple
  • Respect: +567
    • Github
    • Google+
    • bradipao
    • Mostra profilo
  • Dispositivo Android:
    Nexus 5
  • Play Store ID:
    Bradipao
  • Sistema operativo:
    W7
Re:Consiglio ottimizzazione per cronometro
« Risposta #1 il: 11 Ottobre 2011, 13:55:03 CEST »
0
Mi sembra che tu stia "provando" a fare un refresh a 100Hz (10ms), ma che io sappia i display oltre 60Hz non vanno comunque.
NON rispondo a domande nei messaggi privati
Bradipao @ Play Store

Offline andre12

  • Nuovo arrivato
  • *
  • Post: 7
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Motorola Defy
  • Sistema operativo:
    Windows 7
Re:Consiglio ottimizzazione per cronometro
« Risposta #2 il: 11 Ottobre 2011, 14:03:06 CEST »
0
Mmh, interessante osservazione.
Quindi per avere le migliori prestazioni dovrei impostare il tempo di sleep del thread pari all'inverso della frequenza di refresh del display? E' possibile in qualche modo ottenerla?

Offline iceweasel

  • Moderatore globale
  • Utente senior
  • *****
  • Post: 878
  • Respect: +147
    • Mostra profilo
  • Dispositivo Android:
    LGE P990 - Google Nexus 5
  • Sistema operativo:
    Linux Debian Sid
Re:Consiglio ottimizzazione per cronometro
« Risposta #3 il: 11 Ottobre 2011, 14:51:53 CEST »
0
Display.getRefreshRate():

Display | Android Developers
adb logcat | tee /tmp/logcat | grep TAG

Offline andre12

  • Nuovo arrivato
  • *
  • Post: 7
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Motorola Defy
  • Sistema operativo:
    Windows 7
Re:Consiglio ottimizzazione per cronometro
« Risposta #4 il: 11 Ottobre 2011, 15:05:36 CEST »
0
Si, ho già provato quel metodo e mi restituisce 68. Tradotto in millisecondi è 14,7, non un grande cambiamento. Ho fatto un arrotondamento all'intero superiore.Provando però noto comunque qualche impuntamento.
Esiste magari qualche altro parametro da impostare perchè il refresh sia il più fluido possibile?

Offline iceweasel

  • Moderatore globale
  • Utente senior
  • *****
  • Post: 878
  • Respect: +147
    • Mostra profilo
  • Dispositivo Android:
    LGE P990 - Google Nexus 5
  • Sistema operativo:
    Linux Debian Sid
Re:Consiglio ottimizzazione per cronometro
« Risposta #5 il: 11 Ottobre 2011, 17:32:12 CEST »
0
Esiste magari qualche altro parametro da impostare perchè il refresh sia il più fluido possibile?

Gli elementi della UI di Android non sono studiati per essere  molto veloci nell'aggiornamento. Se vuoi la fluidità devi usare la GPU presente nel dispositivo attraverso le OpenGL-ES, in pratica devi sfruttate le API utilizzate nei giochi.
adb logcat | tee /tmp/logcat | grep TAG

Offline andre12

  • Nuovo arrivato
  • *
  • Post: 7
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Motorola Defy
  • Sistema operativo:
    Windows 7
Re:Consiglio ottimizzazione per cronometro
« Risposta #6 il: 11 Ottobre 2011, 17:36:09 CEST »
0
Ah, ok, quindi tu mi consiglieresti di lasciare una textview bianca e di usare quello spazio disegnandoci in corrispondenza la stringa del tempo che scorre?

Offline iceweasel

  • Moderatore globale
  • Utente senior
  • *****
  • Post: 878
  • Respect: +147
    • Mostra profilo
  • Dispositivo Android:
    LGE P990 - Google Nexus 5
  • Sistema operativo:
    Linux Debian Sid
Re:Consiglio ottimizzazione per cronometro
« Risposta #7 il: 11 Ottobre 2011, 19:45:53 CEST »
0
Più che una TextView le OpenGL-ES vogliono una View rettangolare nella quale puoi solo utilizzare le funzioni presenti nella OpenGL-ES (non sono API per principianti, sono molto complesse ma sono molto veloci).
adb logcat | tee /tmp/logcat | grep TAG

Offline andre12

  • Nuovo arrivato
  • *
  • Post: 7
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Motorola Defy
  • Sistema operativo:
    Windows 7
Re:Consiglio ottimizzazione per cronometro
« Risposta #8 il: 12 Ottobre 2011, 12:09:30 CEST »
0
E se provassi con Canvas.drawText? Si dimostrebbe più performante del metodo che sto usando adesso?

Offline bradipao

  • Moderatore globale
  • Utente storico
  • *****
  • Post: 4043
  • keep it simple
  • Respect: +567
    • Github
    • Google+
    • bradipao
    • Mostra profilo
  • Dispositivo Android:
    Nexus 5
  • Play Store ID:
    Bradipao
  • Sistema operativo:
    W7
Re:Consiglio ottimizzazione per cronometro
« Risposta #9 il: 12 Ottobre 2011, 13:39:50 CEST »
0
E se provassi con Canvas.drawText? Si dimostrebbe più performante del metodo che sto usando adesso?

La mia (personalissima) sensazione è che buona parte del tempo lo perdi ad usare il meccanismo messaggi. Per cui se gestisci la visualizzazione direttamente, potrebbe migliorare.
NON rispondo a domande nei messaggi privati
Bradipao @ Play Store

Offline andre12

  • Nuovo arrivato
  • *
  • Post: 7
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Motorola Defy
  • Sistema operativo:
    Windows 7
Re:Consiglio ottimizzazione per cronometro
« Risposta #10 il: 12 Ottobre 2011, 13:46:40 CEST »
0
Eh no, purtroppo da come avevo letto anche nei tutorial presenti su questo forum, solo il thread che gestisce la view può aggiornarla, da qui il meccanismo dei messaggi

Offline bradipao

  • Moderatore globale
  • Utente storico
  • *****
  • Post: 4043
  • keep it simple
  • Respect: +567
    • Github
    • Google+
    • bradipao
    • Mostra profilo
  • Dispositivo Android:
    Nexus 5
  • Play Store ID:
    Bradipao
  • Sistema operativo:
    W7
Re:Consiglio ottimizzazione per cronometro
« Risposta #11 il: 20 Ottobre 2011, 13:38:53 CEST »
0
Eh no, purtroppo da come avevo letto anche nei tutorial presenti su questo forum, solo il thread che gestisce la view può aggiornarla, da qui il meccanismo dei messaggi

Si, ma intendevo direttamente dal thread che disegna la view, senza passare dai messaggi verso l'activity.
NON rispondo a domande nei messaggi privati
Bradipao @ Play Store

Offline andre12

  • Nuovo arrivato
  • *
  • Post: 7
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Motorola Defy
  • Sistema operativo:
    Windows 7
Re:Consiglio ottimizzazione per cronometro
« Risposta #12 il: 20 Ottobre 2011, 13:48:47 CEST »
0
Eh, ma se facessi un ciclo infinito che mi aggiorna il testo che scorre nello stesso thread della gui, questo mi freezerebbe tutto. Almeno cosi credo

Offline bradipao

  • Moderatore globale
  • Utente storico
  • *****
  • Post: 4043
  • keep it simple
  • Respect: +567
    • Github
    • Google+
    • bradipao
    • Mostra profilo
  • Dispositivo Android:
    Nexus 5
  • Play Store ID:
    Bradipao
  • Sistema operativo:
    W7
Re:Consiglio ottimizzazione per cronometro
« Risposta #13 il: 20 Ottobre 2011, 14:05:05 CEST »
0
Eh, ma se facessi un ciclo infinito che mi aggiorna il testo che scorre nello stesso thread della gui, questo mi freezerebbe tutto. Almeno cosi credo

In un thread diverso da quello della GUI, un po' come fanno per i giochi. Se cerchi su google le keywords "android game loop" trovi diverso materiale. Un approccio di quelli proposti è una surfaceview istanziata nella tua gui, in cui un thread dedicato si occupa del ridisegno di tale view. Visto che a te serve spingerti verso 60fps reali, quale miglior approccio di quello dei videogiochi?
NON rispondo a domande nei messaggi privati
Bradipao @ Play Store