Io uso questa strategia, prima dichiaro un gestore e un Runnable in questo modo:
private final Observable mObservable = new Observable();
private final static int TIME_STEP_MS = 5;
private final Handler mHandler = new Handler();
private final Runnable mTimeManager = new Runnable()
{
public void run()
{
mObservable.notifyObservers(TIME_STEP_MS);
mHandler.postDelayed(mTimeManager, TIME_STEP_MS);
}
};
Poi quando voglio iniziare il mio manager volta mi basta chiamare il mTimeManager.run() e inizierà a notificare periodicamente i miei Observer
s (aggiunti in precedenza).
Se avete bisogno per qualche motivo fermare il timer o qualcosa che hai appena fatto questo:
mHandler.removeCallbacks(mTimeManager);
[EDIT - codice più completo]
Ok che cerchiamo di renderlo più chiaro, prima ho fatto un oggetto Observable personalizzato come quello [che è opzionale]:
private final Observable mObservable = new Observable()
{
public void notifyObservers()
{
setChanged();
super.notifyObservers();
};
@Override
public void notifyObservers(Object data)
{
setChanged();
super.notifyObservers(data);
};
};
la ragione di questo è proprio perché io non posso chiamare setChan ged() all'esterno della classe Observable: è protetto, se non viene modificato non notifica alcun osservatore.
Le altre dichiarazioni mantenere lo stesso come mostrato prima, ora ho bisogno di iniziare questa TimeManager
da qualche parte, la mia app è un LiveWallpaper e faccio tutta roba di rendering in una classe che estende una Thread
, ma non è necessario che necessariamente, ho fatto un metodo chiamato resumeDrawing()
, questo è chiamato subito dopo super.start();
alla mia @Override
di public synchronized void start()
da Thread
di classe, il metodo sembra che:
public void resumeDrawing()
{
if (!mTimeManagerRunning) // just a boolean field in my class
{
System.err.println("Resuming renderer."); // just for debug
mTimeManager.run();
mTimeManagerRunning = true;
}
else
{
System.err.println("Renderer already running."); // just for debug
}
}
ed è duplice:
public void pauseDrawing()
{
if (mTimeManagerRunning)
{
System.err.println("Pausing renderer.");
mHandler.removeCallbacks(mTimeManager);
mTimeManagerRunning = false;
}
else
{
System.err.println("Renderer already paused.");
}
}
Ok, ora possiamo avviare e fermare il manager del tempo, ma chi sta ascoltando? Nessuno!add'em di modo da lasciare: sul costruttore del mio renderer aggiungo alcune Observer
s al mio mObservable
oggetto, una di queste è il renderer in sé, quindi il mio renderer estende Thread
e implementa Observer
:
@Override // from Observer interface
public void update(Observable arg0, Object arg1)
{
mElapsedMsRedraw += (Integer) arg1;
if (mElapsedMsRedraw >= mDrawingMsPerFrame)
{
mElapsedMsRedraw = 0;
drawEm(); // refresh the canvas and stuff
}
}
per aggiungere osservatori voi semplicemente fare mObservable.addObserver(THE_OBJECT - Implements Observer)
si può vedere che non mi ri-renderizzare le mie cose ogni volta che sto avvertito, è perché io uso questo TimeManager per altro pensa che solo aggiornare la Canvas
come l'aggiornamento della posizione degli oggetti che voglio disegnare solo internamente.
Quindi, ciò di cui hai bisogno per rallentare il disegno è cambiare il modo in cui gli oggetti cambiano internamente mentre il tempo passa, intendo le tue cerchie e punti ecc. Oppure puoi azzardare il tuo passo temporale, raccomando il primo.
Era più chiaro? Spero possa essere d'aiuto.
thx, ma potresti pubblicare un esempio più completo? Mostrando l'implementazione. – FooBar
Certo, sono al lavoro ora che è il pezzo di codice che potrei ricordare. Me ne vado tra 20 minuti, quindi APPENA POSSIBILE, ti darò un codice più completo. – HericDenis
Ok @FooBar ora sono a casa ti aiuterò (: – HericDenis