在 onStop() 之后,带有线程的 Android 活动被破坏

Posted

技术标签:

【中文标题】在 onStop() 之后,带有线程的 Android 活动被破坏【英文标题】:Android activity with threads get destroyed after onStop() 【发布时间】: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() 永远不会被调用。 尝试像我描述的那样移动超级调用并再次运行,然后再深入研究。 是的,他们追求一切。 【参考方案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 之间切换的速度非常快,该方法可能会失败,但实际上不应该发生这种情况。而且仍然不能保证不会有重复。

【讨论】:

以上是关于在 onStop() 之后,带有线程的 Android 活动被破坏的主要内容,如果未能解决你的问题,请参考以下文章

android中怎样让main线程和子线程同步一个变量

两个Activity启动时候执行的顺序

保存数据返回后可以继续编辑

OnStop() 多次将数据保存到数据库

是否保证调用 Activity.onStop() (API 11 +)

Android:在活动中 onStart()、onStop()、onDestroy() 的开头或结尾调用 super()?