質問

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:

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. I have onPause/onResume defined as:

@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. 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. 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

2) recreates SimulationActivity. onCreate is called for some reason!

3) recreates the GLWorld object inside SimulationActivity

4) calls onResume (I do not know why it does this, it shouldn't from what I understand)

5) calls onPause yet again.

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

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. Notice, the this.mRenderer variable itself does not ever become null. It is the mGrid object inside of it that becomes 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. 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. 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帰属
所属していません StackOverflow
scroll top