简体   繁体   English

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

[英]Android activity with threads get destroyed after onStop()

So I have an activity for a game which holds two extra threads for updating and rendering. 所以我有一个游戏活动,它有两个额外的线程用于更新和渲染。 When I press home (or hide activity in any other means) and return, the screen freezes for some time and the activity restarts like with the last intent. 当我按下主页(或以任何其他方式隐藏活动)并返回时,屏幕会冻结一段时间,并且活动会像最后一个意图一样重新启动。 This especially happens often when I long press home (enter running apps list). 当我长按回家(进入正在运行的应用列表)时,这种情况经常发生。 I assume the problem lies in threads handling here. 我假设问题出在这里的线程处理。

Also 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) 另外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)

Surely, I can store failsafe data with onSave/RestoreInstanceState, but still the freeze occurs and that segfault looks a bit disturbing. 当然,我可以使用onSave / RestoreInstanceState存储故障安全数据,但仍然会发生冻结,并且segfault看起来有点令人不安。

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 - I cannot reproduce it on emulator with API 16 nor 21. It happens on my physical device with API 22. @edit:注意 - 我无法在API 16和21的模拟器上重现它。它发生在我的带有API 22的物理设备上。

I'm not sure 100% if I just found the solution but after applying this and trying a lot to crash the app, I didn't encounter segfault. 我不确定100%如果我刚刚找到解决方案但是在应用了这个并尝试了很多应用程序崩溃后,我没有遇到段错误。 After onStop() I interrupt threads, join the render thread and nullify them. onStop()我中断线程, 加入渲染线程并使它们无效。 onStart() I create new threads basing on runnables. 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();}
}

Surely, here if the app is extremely fast switched between onStop and onStart the method might fail, but this in practice shouldn't happen. 当然,如果应用程序在onStoponStart之间切换非常快,那么方法可能会失败,但实际上这不应该发生。 And still there's no guarantee that there will be no duplicates. 而且仍然不能保证不会有重复。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM