1

更新とレンダリングのために2つの余分なスレッドを保持するゲームのアクティビティがあります。私は家に押して(または他の手段で活動を隠して)戻ると、しばらくの間、画面がフリーズし、最後のインテントのようにアクティビティが再開します。これは、私が長い間家に押し入る(実行中のアプリリストを入力する)ときに特に起こります。ここで扱っているスレッドに問題があると仮定します。onStop()後にAndroidのアクティビティが破棄される

また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)

確かに、私はのOnSave/RestoreInstanceStateでフェイルセーフデータを保存することができますが、それでもフリーズが発生し、そのセグメンテーション違反が少し不安になります。

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:注意 - 私はちょうど見つけた場合、私は確信して100%ではないよAPI 16もそれはAPI 22

+0

'onStop()'と 'onDestroy()'に 'Log'を使って、クラッシュが発生していることを判断できるかどうかを確認してください。また、 'super.onStop()'と 'super.onDestroy()'をそれぞれのメソッドの最後に移動します。 – nukeforum

+0

'onStop()'が起こった後、sigsegvが発生します。 'onDestroy()'は決して呼び出されません。 – pfoof

+0

説明したようにスーパーコールを移動してから、もう一度実行してみてください。 – nukeforum

答えて

0

と私の物理デバイス上で発生した21で、エミュレータ上でそれを再現することはできませんこれを適用してアプリをクラッシュさせるために多くを試した後、私はsegfaultに遭遇しなかった。 onStop()がスレッドを中断した後、がレンダリングスレッドに参加し、それらを無効にします。 onStart()私はrunnablesに基づいて新しいスレッドを作成します。

アプリは非常に高速 onStoponStartの間で切り替えられた場合
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();} 
} 

確かに、ここでの方法は失敗することがありますが、これは実際は発生しないはずです。それでも重複がないという保証はありません。

関連する問題