有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java Android SurfaceView/多线程混乱,线程卡在“信号捕捉器循环”中

我一直在为Android开发一种游戏引擎,但我有一些严重的稳定性问题

我使用一个SurfaceView和一个实现的Runnable来进行多线程处理,以获得我的主/UI线程的一些工作。该类的简化版本如下所示:

private class MenuView extends SurfaceView implements Runnable
{
    Thread T = null;
    SurfaceHolder holder;
    Canvas c;
    boolean run;

    public MenuView(Context context) {
        super(context);
        holder = getHolder();
    }

    @Override
    public void run() {
        while(run)
        {
            if(!holder.getSurface().isValid())
            {
                continue;
            }
            c = holder.lockCanvas();

    //Doing updates and drawing stuff

            holder.unlockCanvasAndPost(c);
        }
    }


    public void pause()
    {
        run = false;
        try
        {
            T.join();
        }
        catch (InterruptedException e)
        {
            Log.e("Error:", "joining thread failed!");
        }
    }

    public void resume()
    {
        run = true;
        T = new Thread(this);
        T.start();
    }

    //bunch of helper methods with no effect on this problem :(

}

如您所见,我的“Worker”线程被捕获在一个无限while循环中,该循环由“run”布尔值控制,该布尔值是使用在我的活动的onPause()和onResume()方法中调用的pause()和resume()方法设置的,如下所示:

MenuView menuV;
Random Rand = new Random();

@Override
protected void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    Screen = getRealScreenSize(getApplicationContext());
    menuV = new MenuView(this);
    menuV.setOnTouchListener(this);
    logoV = new LogoView(this);
    setContentView(logoV);                          Log.d("APP", "SET LOGO VIEW");
//^ This is my splash screen, again irrelevant to the issue, after few seconds of running, this view calls the resume() of my SurfaceView and sets it as the contentView.
}

@Override
protected void onPause() {
    super.onPause();
    Log.d("APP", "ON PAUSE");
    menuV.pause();
}

@Override
protected void onResume() {
    super.onResume();
        getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);

//^hides the goddamn navigation bar...

    Log.d("APP", "ON RESUME");
    menuV.resume();
}

    @Override
public boolean onTouch(View v, MotionEvent event) {

    if(event.getAction() == MotionEvent.ACTION_DOWN)
    {
        Log.d("APP", "ON TOUCH DOWN");
        for(int i = 0; i < menuV.button.length ; i++)
        {
            if(menuV.button[i].active)
            {
                if(event.getX() > menuV.button[i].pos.left && event.getX() < menuV.button[i].pos.right && event.getY() > menuV.button[i].pos.top && event.getY() < menuV.button[i].pos.bottom)
                {
                    menuV.button[i].pressed = true;
                    return true;
                }
            }
        }
    }
    else if(event.getAction() == MotionEvent.ACTION_UP)
    {
        Log.d("APP", "ON TOUCH UP");
        for(int i = 0; i < menuV.button.length ; i++)
        {
            menuV.button[i].pressed = false;
        }
    }

    return false;
}

所以我的触摸事件由UI线程处理,但它是工作线程不断使用的访问信息,同样的事情发生在onPause()和onResume()中,UI线程正在更改工作线程始终使用的“run”布尔值,我这么说是因为当触摸屏幕、关机和开机时,ANR似乎正在发生。渲染没有停止,工作线程似乎很好,但UI线程严重出错,它停止响应,这行代码显示在我的Android监视器上:

线程[2,tid=18257,WaitingMain信号捕捉器LOOP,线程*=0x558cbf1310,对等方=0x12c470a0,“信号捕捉器”]:对信号3做出反应

将堆栈跟踪写入“/data/anr/traces”。txt'

如果还有其他有用的信息,请告诉我——我会在这一行之后编辑您指出的任何重要信息,谢谢


共 (0) 个答案