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) 个答案