[英]Object in openGL scene becomes null in android thread when onPause is called
So this is my first time threading, and i'm using to update a scene at continuous intervals. 所以这是我的第一次穿线,我正在以连续的时间间隔更新场景。 I have been working on this problem and looking around for an explanation everywhere, this is my last resort to my headache.
我一直在研究这个问题,并四处寻找解释,这是我头疼的最后一招。 In my
GLWorld extends GLSurfaceView
class I have a handler being created in this: 在我的
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);
}
the thread it runs is this one: 它运行的线程是这个:
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);
}
};
now the GLWorld object exists inside an activity called SimulationActivity
. 现在GLWorld对象存在于名为
SimulationActivity
的活动中。 I have onPause/onResume defined as: 我有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");
}
where endthread/startthread just sent running to false/true respectively. 其中endthread / startthread刚发送的运行分别为false / true。 My problem is that when I, say click the lock button on the side of my screen to lock the screen, it does some stuff I do not understand why, and I have been trying to figure it out, as well as tries to use an object set to null by the OS in the thread.
我的问题是,当我说单击屏幕侧面的锁定按钮以锁定屏幕时,它做了一些我不理解为什么的事情,并且我一直在试图找出答案,并尝试使用操作系统中的线程将对象设置为null。 What i see it doing (just when I lock the screen, I DON"T even resume it yet) with my logs is that it
我看到它在日志中所做的事情(只是在锁定屏幕时,我什至不恢复它)
1) calls onPause
, does the what's inside there correctly 1)调用
onPause
,正确执行里面的内容
2) recreates SimulationActivity
. 2)重新创建
SimulationActivity
。 onCreate
is called for some reason! 由于某种原因调用了
onCreate
!
3) recreates the GLWorld
object inside SimulationActivity
3)在
SimulationActivity
内部重新创建GLWorld
对象
4) calls onResume
(I do not know why it does this, it shouldn't from what I understand) 4)调用
onResume
(我不知道为什么这样做,我不应该理解)
5) calls onPause
yet again. 5)再次调用
onPause
。
6) now a thread of the tickThread starts running, I don't know why, since it should have been stopped with running
set to false in at least the second onPause
6)现在tickThread的一个线程开始运行,我不知道为什么,因为它应该至少在第二个
onPause
通过将running
设置为false来停止
7) this thread runs the first cycle fine, then the second run throws a null pointer exception in my updateFire
function when I try to access the object inside the renderer called mGrid. 7)当我尝试访问名为mGrid的渲染器中的对象时,该线程在第一个周期运行良好,然后第二个运行在
updateFire
函数中引发了空指针异常。 Notice, the this.mRenderer
variable itself does not ever become null. 注意,
this.mRenderer
变量本身永远不会为空。 It is the mGrid
object inside of it that becomes null 正是其中的
mGrid
对象变为null
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
}
Honestly, I don't even know if i'm threading right anymore. 老实说,我什至不知道我是否正在正确处理线程。
It was a stupidly simple fix I spent so much time trying to find the "right" way to do it. 这是一个愚蠢的简单修复程序,我花了很多时间试图找到“正确”的方法。
private Runnable tickThread = new Runnable()
{
public void run()
{
if(!running)
return;
this is what I did. 这就是我所做的。 I don't know if this is correct, but it was the only thing I figured out after trying dozens of different "solutions".
我不知道这是否正确,但这是我尝试了数十种不同的“解决方案”后唯一想到的。
I'll try to more of my question in case anyone else runs into this. 我会尝试更多的问题,以防其他任何人遇到这个问题。
So the main reason why it calls onResume after onCreate is due to the app activity life cycle android activity life cycle It seems that onResume is always called after onCreate. 因此,它在onCreate之后调用onResume的主要原因是由于应用程序活动生命周期android活动生命周期似乎onResume总是在onCreate之后调用。 As far as the onCreate happening after onPause, that is only when the lock key is pressed while the app is running in the foreground.
就onCreate之后发生的onCreate而言,只有在应用程序在前台运行时才按下锁定键。 I'm going to test the answer found here to remedy that issue.
我将测试此处找到的答案以纠正该问题。 If that link works as I hope it does, then this issue will be resolved.
如果该链接能按我希望的那样工作,那么此问题将得到解决。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.