簡體   English   中英

當調用onPause時,openGL場景中的對象在android線程中變為空

[英]Object in openGL scene becomes null in android thread when onPause is called

所以這是我的第一次穿線,我正在以連續的時間間隔更新場景。 我一直在研究這個問題,並四處尋找解釋,這是我頭疼的最后一招。 在我的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。 我的問題是,當我說單擊屏幕側面的鎖定按鈕以鎖定屏幕時,它做了一些我不理解為什么的事情,並且我一直在試圖找出答案,並嘗試使用操作系統中的線程將對象設置為null。 我看到它在日志中所做的事情(只是在鎖定屏幕時,我什至不恢復它)

1)調用onPause ,正確執行里面的內容

2)重新創建SimulationActivity 由於某種原因調用了onCreate

3)在SimulationActivity內部重新創建GLWorld對象

4)調用onResume (我不知道為什么這樣做,我不應該理解)

5)再次調用onPause

6)現在tickThread的一個線程開始運行,我不知道為什么,因為它應該至少在第二個onPause通過將running設置為false來停止

7)當我嘗試訪問名為mGrid的渲染器中的對象時,該線程在第一個周期運行良好,然后第二個運行在updateFire函數中引發了空指針異常。 注意, this.mRenderer變量本身永遠不會為空。 正是其中的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
}  

老實說,我什至不知道我是否正在正確處理線程。

這是一個愚蠢的簡單修復程序,我花了很多時間試圖找到“正確”的方法。

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

這就是我所做的。 我不知道這是否正確,但這是我嘗試了數十種不同的“解決方案”后唯一想到的。

我會嘗試更多的問題,以防其他任何人遇到這個問題。

因此,它在onCreate之后調用onResume的主要原因是由於應用程序活動生命周期android活動生命周期似乎onResume總是在onCreate之后調用。 就onCreate之后發生的onCreate而言,只有在應用程序在前台運行時才按下鎖定鍵。 我將測試此處找到的答案以糾正該問題。 如果該鏈接能按我希望的那樣工作,那么此問題將得到解決。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM