1

J'ai donc une activité pour un jeu qui contient deux threads supplémentaires pour la mise à jour et le rendu. Lorsque j'appuie sur home (ou que je cache une activité dans un autre moyen) et que je reviens, l'écran se fige pendant un certain temps et l'activité redémarre comme avec la dernière intention. Cela arrive souvent quand je presse longtemps à la maison (entrer la liste des applications en cours d'exécution). Je suppose que le problème réside dans la manipulation des threads ici.L'activité Android avec les threads est détruite après onStop()

également 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)

Sûrement, je peux stocker des données avec sécurité intégrée onSave/RestoreInstanceState, mais le gel se produit et que segfault semble un peu inquiétant.

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: Note - Je ne peux pas le reproduire sur l'émulateur avec l'API 16 ni 21. Il arrive sur mon appareil physique avec l'API 22.

+0

Utilisez 'Log' dans' onStop() 'et' onDestroy() 'et voyez si vous pouvez déterminer après quoi l'incident se produit. Déplacez également 'super.onStop()' et 'super.onDestroy()' au bas de leurs méthodes respectives. – nukeforum

+0

'onStop()' arrive, puis sigsegv. 'onDestroy()' n'est jamais appelé. – pfoof

+0

Essayez de déplacer les super-appels comme je l'ai décrit et exécutez à nouveau avant de plonger trop profondément dans cela. – nukeforum

Répondre

0

Je ne suis pas sûr à 100% si je viens de trouver la solution, mais après avoir appliqué cela et essayer beaucoup de planter l'application, je n'ai pas rencontré segfault. Après onStop() j'interrompre les threads, rejoindre le thread de rendu et de les annuler. onStart() Je crée de nouveaux threads basés sur des 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();} 
} 

Sûrement, ici si l'application est extrêmement rapide entre marche et onStoponStart la méthode peut échouer, mais dans la pratique ne devrait pas se produire. Et encore il n'y a aucune garantie qu'il n'y aura pas de doublons.