所以这是我的第一次线程,我正在使用连续更新场景。我一直在研究这个问题,到处寻找解释,这是我最后的理由。在我的GLWorld extends GLSurfaceView
课程中,我创建了一个处理程序:
private static int threadID = 0;
private final WorldRenderer mRenderer;
private boolean running;
private Context context;
Handler timeHandler;
private int[] values;
public GLWorld(Context context, int values[])
{
super(context);
this.context = context;
timeHandler = new Handler();
// Create an OpenGL ES 2.0 context.
setEGLContextClientVersion(2);
// Set the Renderer for drawing on the GLSurfaceView
Log.d("Test", "GL initialized");
mRenderer = new WorldRenderer(context, values);
setRenderer(mRenderer);
this.startThread();
timeHandler.postDelayed(tickThread, values[2] * 1000);
// Render the view only when there is a change in the drawing data
setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
}
它运行的线程就是这个:
private Runnable tickThread = new Runnable()
{
public void run()
{
threadID++;
Log.d("tick", "start " + threadID + " " + SystemClock.currentThreadTimeMillis());
ArrayList<Point> points = new ArrayList<Point>();
//work down and populate points not shown
for(int i = 0; i < values[0]; i++)
{
for(int j = 0; j < values[1]; j++)
{
updateFire(i,j,points);
points.clear();
}
}
requestRender();
Log.d("tick", "finish " + threadID + " " + SystemClock.currentThreadTimeMillis());
Log.d("","");
if(running)
timeHandler.postDelayed(this, values[2]* 1000);
}
};
现在,GLWorld对象存在于名为SimulationActivity
的活动中。我将onPause / onResume定义为:
@Override
protected void onPause()
{
super.onPause();
// The following call pauses the rendering thread.
// If your OpenGL application is memory intensive,
// you should consider de-allocating objects that
// consume significant memory here.
mGLView.endThread();
mGLView.onPause();
Log.d("pause","pause called");
}
@Override
protected void onResume()
{
super.onResume();
// The following call resumes a paused rendering thread.
// If you de-allocated graphic objects for onPause()
// this is a good place to re-allocate them.
mGLView.onResume();
mGLView.startThread();
Log.d("resume","resume called");
}
其中endthread / startthread分别发送运行为false / true。我的问题是,当我说,点击屏幕侧面的锁定按钮锁定屏幕,它做了一些我不明白的原因,我一直试图弄明白,以及尝试使用对象由线程中的OS设置为null。我看到它做什么(就在我锁定屏幕时,我甚至还没有恢复它)我的日志就是它
1)调用onPause
,正确处理内部的内容
2)重新创建SimulationActivity
。 onCreate
因某种原因被召唤!
3)在GLWorld
SimulationActivity
对象
4)调用onResume
(我不知道为什么会这样做,不应该根据我的理解)
5)再次呼叫onPause
。
6)现在tickThread的一个线程开始运行,我不知道为什么,因为它应该在至少第二个running
onPause
设置为false的情况下停止
7)当我尝试访问名为mGrid的渲染器内的对象时,此线程运行第一个循环正常,然后第二次运行在我的updateFire
函数中抛出空指针异常。请注意,this.mRenderer
变量本身不会变为空。它内部的mGrid
对象变为空
private void updateFire(int i, int j, ArrayList<Point> surroundingPoints)
{
//check if renderer or the object is null
if(this.mRenderer == null)
Log.d("grid","null");
else
Log.d("grid","stuff");
GridSquare currGrid = this.mRenderer.mGrid[i*values[1] + j];
//do non question importance stuff
}
老实说,我甚至不知道我是否正在穿线。
答案 0 :(得分:0)
这是一个愚蠢的简单修复,我花了很多时间试图找到“正确”的方法来做到这一点。
private Runnable tickThread = new Runnable()
{
public void run()
{
if(!running)
return;
这就是我所做的。我不知道这是否正确,但在尝试了几十种不同的“解决方案”之后,这是我唯一想到的。
如果有其他人遇到此问题,我会尝试更多问题。
因此,在onCreate之后调用onResume的主要原因是应用程序活动生命周期android activity life cycle似乎onResume总是在onCreate之后调用。至于在onPause之后发生的onCreate,只有当应用程序在前台运行时才按下锁定键。我将测试here找到的答案来解决这个问题。如果该链接按照我希望的方式工作,那么这个问题将得到解决。