2009-04-27 17 views
14

Sto sviluppando un gioco per Android. Sta succedendo molto ma sta funzionando abbastanza bene. Questo è, naturalmente, fino a quando l'utente tocca lo schermo.Perché gli eventi tattili stanno distruggendo il mio framerate Android?

mentre sono toccarlo, onTouchEvent si chiama (con action = ACTION_MOVE, x = 0 e y = 0) circa una volta ogni dieci millisecondi a quello che sembra essere abbastanza alta priorità, come assolutamente cancella il framerate. Non appena il tocco termina, il framerate torna al suo stato piacevole.

Ho provato

  • aver inserito onTouchEvent maniglia per il gioco come al solito
  • avere onTouchEvent ritorno true subito
  • non avere onTouchEvent implementati a tutti i

il problema persiste in tutte e tre le situazioni.

Qualcuno ha riscontrato questo? Esiste un modo per ridurre la frequenza con cui vengono generati gli eventi ACTION_MOVE o per garantire che vengano generati solo quando esiste un movimento effettivo oppure utilizzare un metodo di polling che ottiene solo la posizione corrente del tocco? O anche solo un modo per disabilitarlo del tutto?

risposta

12

Read questa discussione. Fondamentalmente si vuole dormire il thread dell'evento poiché altrimenti il ​​sistema pompa un sacco di eventi (tra x, y e pressione c'è sempre movimento in corso) che è necessario gestire.

+0

link non funziona più. –

0

Forse una soluzione un po 'ovvia, ma ... hai provato a gestire solo circa 1/10 di loro? Se stai eseguendo un'elaborazione che viene attivata ogni 10 ms sul thread dell'interfaccia utente, è probabile che rallenti il ​​framerate, sì. Quindi, cosa succede se si accumula un contatore in qualche modo invece e si esegue qualsiasi elaborazione solo una volta superata una soglia minima?

1

Ho cercato di seguire tutto ciò che voi ragazzi hanno parlato circa, ma devo ammettere che dopo aver provato diversi modi di attuazione quello che suggeriscono, non ho ancora stato in grado di raggiungere qualsiasi positiva risultati. Qualcuno di voi potrebbe fornire qualche codice di esempio? In particolare, Mi piacerebbe sapere come procedere per rendere il thread principale/dell'interfaccia utente inattivo. Se è applicabile ai miei giochi, sarebbe anche bello sapere come impostare su un modello di sondaggio come Jon implementato.

Ecco come appare il mio codice. Sul thread UI:

public boolean onTouchEvent(MotionEvent event) { 
    // Store event somewhere the game thread can see it: 
    // ... 

    synchronized (someObject) { 
     try { 
      someObject.wait(1000L); 
     } catch (InterruptedException e) { 
     } 
    } 

    return true; 
} 

e sul filo del gioco:

void myGame() { 
    while (!stopping) { 
     // ... 

     // Get a touch event: 
     synchronized (someObject) { 
      someObject.notify(); 
     } 
     Thread.yield(); 

     // ... 
    } 
} 
0

Se si desidera una soluzione senza avere a che fare con i fili di sincronizzazione posso consigliare utilizzando l'interfaccia Handler per inviare l'evento e pertinenti dati utilizzando un messaggio/pacchetto per il thread di rendering del gioco. La soluzione del sonno suggerita qui vale ancora.

0

Generalmente gli eventi sono dotati di una proprietà di timestamp, quindi è facile calcolare e limitare la frequenza degli eventi.

if (currentEventTimestamp - lastEventTimestamp > 500) { 
 

 
    lastEventTimestamp = currentEventTimestamp; 
 

 
    // do something 
 

 
}

Problemi correlati