IllegalThreadStateException Android in LunarLander
-
22-08-2019 - |
Domanda
Appena arrivato a lucidare la mia domanda e rendendo riprendere dopo che l'utente ha lasciato. Quando l'applicazione ripristina ottengo un IllegalThreadStateException, che è abbastanza fastidioso. Questo problema è presente nell'esempio Google dà di Lunar Lander . Qualcuno ha trovato un modo per ripristinare lavorare quando si utilizza SurfaceView?
Soluzione
Credo che questo deriva da una disparità nel modo in cui la superficie e l'attività sono gestite. Quando si lascia l'applicazione LunarLander la superficie viene distrutta (invocando surfaceDestroyed), ma l'attività è in pausa solo (invocando onPause). Quando l'attività è ripresa viene creata la superficie (invocando surfaceCreated) e tenta di ricominciare il filo disegno.
Ciò significa che la creazione della filettatura avviene con ciclo di vita del attività e distruggendo il filo avviene con ciclo di vita del SurfaceView, che non sempre corrispondono, così l'IllegalThreadStateException. La soluzione potrebbe essere quella di legare il filo ad una vita o l'altro, non entrambi.
questa discussione propone una possibile soluzione, anche se non so se funziona.
Altri suggerimenti
Nel mio test, ho creare il filo disegno nel metodo surfaceCreated (), e questo risolve completamente il problema. Questo è il mio metodo di implementazione:
@Override
public void surfaceCreated(SurfaceHolder arg0) {
_thread = new DrawThread(getHolder());
_thread.setRunning(true);
_thread.start();
}
Quindi, nel codice, quando surfaceDestroyed()
viene chiamato, imposta mRun
false e chiede thread.join()
. Ciò causa il filo per completare e morire. Quando l'applicazione viene avviata di nuovo e surfaceCreated()
si chiama, chiama thread.start()
. Questo è valido perché il filo non può essere avviato dopo muore.
Due opzioni per risolvere:
a) Inizia un nuovo thread in surfaceCreated()
-. Come sopra
b) o aggiungere un controllo in surfaceDestroyed()
contro Activity.isFinishing()
per terminare solo il thread se vero. Per fare questo, ho circondato la while(mRun)
nel thread con un altro ciclo while che è impostato solo su false se isFinishing()
restituisce true.