I have such a class
class C
{
MainActivity mainActivity;
boolean isPaused;
public void A()
{
B b = new B()
{
public void run()
{
isDone = true;
}
};
mainActivity.runOnUiThread(b);
while(!b.isDone && !isPaused)
{
try { Thread.sleep(1); }
catch(Exception e)
{
e.printStackTrace();
break;
}
}
}
}
abstract class B implements Runnable
{
public boolean isDone = false;
}
Then it is called in renderer that implements GLSurfaceView.Renderer
@Override
public void onDrawFrame(GL10 gl)
{
c.A();
}
c is instanceof C and, mainActivity call GLSurfaceView.onPause and onResume when onPause and onResume of itself called. It also set isPaused of c. GLSurfaceView's onPause and onResume just call its super's onPause and onResume.
Then when onPause and onResume called, my app is freezed. To find the problem, I removed other code except what I explained, but it still occurs. How can I fix it?
onDrawFrame
is being executed on the UI thread. You are blocking the thread indefinitely because you are never going to have !b.isDone && !isPaused
evaluate to false. You should never call Thread.sleep()
on the main UI thread.
EDIT:
I was actually wrong about this. The renderer is called from a separate thread to prevent such a block on the UI thread. However, there is still an issue with sharing a variable (isDone) between the two threads. This can be overcome by making isDone volatile
.