【问题标题】:Android activity with threads get destroyed after onStop()在 onStop() 之后,带有线程的 Android 活动被破坏
【发布时间】:2016-11-04 04:34:50
【问题描述】:

所以我有一个游戏活动,其中包含两个用于更新和渲染的额外线程。当我按下主页(或以任何其他方式隐藏活动)并返回时,屏幕会冻结一段时间,活动会重新启动,就像最后一个意图一样。当我长按主页(进入正在运行的应用程序列表)时,这尤其经常发生。我认为问题在于这里的线程处理。

还有 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:注意 - 我无法在具有 API 16 或 21 的模拟器上重现它。它发生在具有 API 22 的物理设备上。

【问题讨论】:

  • onStop()onDestroy() 中使用Log,看看您是否可以确定发生崩溃的时间。另外,将super.onStop()super.onDestroy() 移动到各自方法的底部。
  • onStop() 发生,然后是 sigsegv。 onDestroy() 永远不会被调用。
  • 尝试像我描述的那样移动超级调用并再次运行,然后再深入研究。
  • 是的,他们追求一切。

标签: android multithreading android-activity activity-lifecycle


【解决方案1】:

如果我刚刚找到解决方案,我不确定 100%,但在应用此解决方案并尝试很多使应用程序崩溃后,我没有遇到段错误。在onStop() 中断线程后,加入 渲染线程并取消它们。 onStart()我基于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();}
}

当然,如果应用在onStoponStart 之间切换的速度非常快,该方法可能会失败,但实际上不应该发生这种情况。而且仍然不能保证不会有重复。

【讨论】:

    猜你喜欢
    • 2013-04-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多