2014-01-18 28 views
0

所以这是我第一次穿线,而且我正在用连续的间隔更新一个场景。我一直在研究这个问题,四处寻找解释,这是我最头痛的最后一招。在我GLWorld extends GLSurfaceView类我在这所创建的处理程序:当onPause调用时,openGL场景中的对象在android线程中变为null

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。我看不出它(只是当我锁定屏幕,我DON“T甚至恢复它尚未)与我的日志是它

1)调用,莫非是里面有什么有正确

2)再现SimulationActivityonCreate被称为出于某种原因!

3)再现内部SimulationActivity

4)GLWorld对象调用onResume(我不知道为什么这样做,它不应该从我的理解)

5)再次呼叫。

6)现在tickThread的线程开始运行,我不知道为什么,因为它应该已经停止了与running设置为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

这是一个愚蠢简单的修复,我花了很多时间试图找到“正确”的方式来做到这一点。

private Runnable tickThread = new Runnable() 
{ 
    public void run() 
    { 
     if(!running) 
      return; 

这就是我所做的。我不知道这是否正确,但这是我尝试了几十种不同的“解决方案”之后唯一想到的。

我会尝试更多的我的问题,以防其他人遇到这种情况。

所以它在onCreate之后调用onResume的主要原因是由于应用程序活动生命周期android activity life cycle看来,onResume总是在onCreate之后调用。至于在onPause之后发生的onCreate,只有当应用程序在前台运行时按下锁定键。我要测试回答发现here来解决这个问题。如果该链接按我希望的那样工作,那么这个问题将得到解决。