1

So habe ich eine Aktivität für ein Spiel, das zwei zusätzliche Threads zum Aktualisieren und Rendern enthält. Wenn ich nach Hause drücke (oder die Aktivität auf irgendeine andere Weise verberge) und zurückkehre, bleibt der Bildschirm für einige Zeit stehen und die Aktivität startet wie bei der letzten Absicht neu. Dies passiert besonders oft, wenn ich lange nach Hause drücke (Eingabe der laufenden Apps-Liste). Ich nehme an, das Problem liegt in den Threads, die hier behandelt werden.Android-Aktivität mit Threads werden nach onStop() zerstört

Auch Logcat: 07-01 16:52:28.793 28502-28603/com.example.game A/libc: Fatal signal 11 (SIGSEGV), code 1, fault addr 0x7f95401a20 in tid 28603 (Thread-5887)

Sicher, ich Failsafe-Daten mit onSave/RestoreInstanceState speichern kann, aber immer noch der Frost auftritt und dass segfault sieht ein wenig störend.

public class GameActivity extends AppCompatActivity { 
    private Thread renderThread,updateThread; 
    private boolean ActivityHidden=false,Pause=false,Alive=true; 
    private int renderSleep=25; 

    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     //Constructing stuffs 
     renderThread = new Thread(renderRunanble); 
     updateThread = new Thread(updateRunnable); 
    } 

    public void render(){ 
     if(ActivityHidden) return; 
     //Rendering... 
    } 

    protected void onPause(){ 
     super.onPause(); 
     Paused=true; 
    } 

    protected void onResume(){ 
     super.onResume(); 
     if(!renderThread.isAlive()) renderThread.start(); 
     if(!updateThread.isAlive()) updateThread.start(); 
    } 

    protected void onStop() { 
     super.onStop(); 
     ActivityHidden=true; 
     renderSleep=250; 
    } 

    protected void onStart() { 
     super.onStart(); 
     ActivityHidden=false; 
     renderSleep=25; 
    } 

    protected void onDestroy() { 
     super.onDestroy(); 
     Alive=false; 
     try {renderThread.join();} catch(Exception e) {} 
    } 

    private Runnable renderRunnable = new Runnable() { 
     public void run() { 
      while(Alive) { 
       render(); 
       try {Thread.sleep(renderSleep);} catch(Exception e){} 
      } 
     } 
    }; 

    private Runnable updateRunnable = new Runnable() { 
     public void run() { 
      while(Alive) { 
       if(!Paused) 
       //updates happening 
       try {Thread.sleep(25);} catch(Exception e){} 
      } 
     } 
    }; 
} 

@edit: Hinweis - ich kann es nicht mit API 16 noch 21. Es geschieht auf meinem physischen Gerät mit API 22

+0

Verwenden Sie 'Log' in' onStop() 'und' onDestroy() 'und sehen Sie, ob Sie bestimmen können, nach welchem ​​Absturz der Absturz auftritt. Verschieben Sie auch 'super.onStop()' und 'super.onDestroy()' an den unteren Rand der jeweiligen Methoden. – nukeforum

+0

'onStop()' passiert, dann Sigsegv. 'onDestroy()' wird nie aufgerufen. – pfoof

+0

Versuchen Sie, die Super-Anrufe zu verschieben, wie ich es beschrieben habe, und laufen Sie noch einmal, bevor wir zu tief hinein tauchen. – nukeforum

Antwort

0

Ich bin nicht sicher 100% auf Emulator reproduzieren, wenn ich fand nur die Lösung, aber nachdem ich dies angewendet und viel versucht habe, die App zum Absturz zu bringen, stieß ich nicht auf segfault. Nach onStop() Interrupt Threads, Join der Render-Thread und sie aufheben. onStart() Ich erstelle neue Threads basierend auf Runnables.

protected void onStop() { 
    ActivityHidden=true; 
    Alive=false; 
    renderSleep=250; 
    updateThread.interrupt(); 
    renderThread.interrupt(); //Sometimes don't happen because it's still rendering 
    try {renderThread.join();} catch(Exception e){} 
    updateThread=null; 
    renderThread=null; 
    super.onStop(); 
} 

protected void onStart() { 
    super.onStart(); 
    ActivityHidden=false; 
    Alive=true; 
    renderSleep=25; 
    if(updateThread==null) {updateThread = new Thread(updateRunnable); updateThread.start();} 
    if(renderThread==null) {renderThread = new Thread(renderRunnable); renderThread.start();} 
} 

Sicher, hier, wenn die App extrem schnell geschaltet werden zwischen onStop und onStart das Verfahren scheitern könnte, aber dies in der Praxis soll nicht passieren. Und trotzdem gibt es keine Garantie, dass es keine Duplikate geben wird.

Verwandte Themen