在 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();
当然,如果应用在onStop
和onStart
之间切换的速度非常快,该方法可能会失败,但实际上不应该发生这种情况。而且仍然不能保证不会有重复。
【讨论】:
以上是关于在 onStop() 之后,带有线程的 Android 活动被破坏的主要内容,如果未能解决你的问题,请参考以下文章
是否保证调用 Activity.onStop() (API 11 +)
Android:在活动中 onStart()、onStop()、onDestroy() 的开头或结尾调用 super()?