4

我再次需要一些帮助:

昨天我问了这个关于使用大 jpg 图像作为位图的方法的问题(http://stackoverflow.com/questions/13511657/problems-with-big-drawable-jpg-image)我自己解决了(是我自己对那个问题的回答)但是每当我恢复我的活动时,因为它使用该位图作为 GLRenderer 纹理它会崩溃。我已经尝试了很多事情,最后一次尝试是使该位图静态,以便将其作为成员变量保留到活动中,但它崩溃了,因为我想它失去了它的 mBuffer。

有关活动代码的更多详细信息:

我在清单中将其声明为 SingletonInstance:

android:launchMode="singleInstance"

为了保留渲染器的瓷砖。

这里有一些代码:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    mGLSurfaceView = new GLSurfaceView(this);
    mGLSurfaceView.setEGLConfigChooser(true);   
    mSimpleRenderer = new GLRenderer(this);

    getTextures();      

    if (!mIsTileMapInitialized){

        tileMap = new LandSquareGrid(1, 1, mHeightmap, mLightmap, false, true, true, 128, true);
        tileMap.setupSkybox(mSkyboxBitmap, true);
        mIsTileMapInitialized = true;
    }

    initializeRenderer();   
    mGLSurfaceView.setRenderer(mSimpleRenderer);

    setContentView( R.layout.game_layout );

    setOnTouchListener();
    initializeGestureDetector();

    myCompassView = (MyCompassView)findViewById(R.id.mycompassview);

    // Once set the content view we can set the TextViews:
    coordinatesText = (TextView) findViewById(R.id.coordDynamicText); 
    altitudeText = (TextView) findViewById(R.id.altDynamicText); 
    directionText = (TextView) findViewById(R.id.dirDynamicText); 

    //if (!mIsGLInitialized){
    mOpenGLLayout = (LinearLayout)findViewById(R.id.openGLLayout);
    mOpenGLLayout.addView(mGLSurfaceView);
    mVirtual3DMap = new Virtual3DMap(mSimpleRenderer, tileMap);

    if (mGameThread == null){
        mGameThread = new Thread(mVirtual3DMap);
        mGameThread.start();
    }

}

在 getTextures 方法上,我得到了一些小的纹理,而最大的纹理与我最后一个问题的自我回答一样:

    if (mTerrainBitmap==null){
        InputStream is = getResources().openRawResource(R.drawable.terrain);
        try {
            // Set terrain bitmap options to 16-bit, 565 format.
            terrainBitmapOptions.inPreferredConfig = Bitmap.Config.RGB_565;
            Bitmap auxBitmap = BitmapFactory.decodeStream(is, null, terrainBitmapOptions);
            mTerrainBitmap = Bitmap.createBitmap(auxBitmap);
        }
        catch (Exception e){

        }
        finally {
            try {
                is.close();
            } 
            catch (IOException e) {
                // Ignore.
            }
        }
    }

所以,再一次,它第一次效果很好,但是当我回去时,我这样做了:

protected void onPause() {
    super.onPause();
    mGLSurfaceView.onPause();

}
@Override
protected void onStop() {
    // TODO Auto-generated method stub
    super.onStop();
    if (mVirtual3DMap != null) {
        try {
            mVirtual3DMap.cancel();
            mGameThread=null;
            mVirtual3DMap = null;
            mGLSurfaceView.destroyDrawingCache();
            mSimpleRenderer=null;
            System.gc();
        } catch (Throwable e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }   

}

当我恢复活动时:

@Override
protected void onResume() {
    super.onResume();
    mGLSurfaceView.onResume();
    if (mVirtual3DMap != null) {
        try {
            mVirtual3DMap.resume();
        } catch (Throwable e) {
            e.printStackTrace();
        }
    }
}

它崩溃了。

为什么??好的,这是 GLThread 上的异常原因:

java.lang.IllegalArgumentException: 位图被回收...

我尝试了这些乱七八糟的东西,因为启动两倍以上的原始活动导致应用程序崩溃,或者因为使用的内存量,现在我不知道是否恢复所有这些更改或如何处理。

有没有一种好方法可以通过这个或另一个应用程序活动来保持内存和可用,这个位图?

拜托,我需要你的建议。

提前致谢。

4

2 回答 2

2

不要手动处理资源,否则您的应用程序的表面会崩溃。您无法手动处理资源。

如果您担心重新加载资源并且使用 API 级别 11+,则可以使用setPreserveEGLContextOnPause()。它将保留您的纹理和 FBO。

如果您不能使用 API 11+,您可以移植GLSurfaceView()到您的应用程序。您可以检查我自己的从 ICS 移植的 GLSurfaceView

PS:对不起我的英语不好。

于 2012-11-27T15:56:33.760 回答
0

不,让 Android 处理所有资源。当活动恢复时,您必须处理适当的事件并重新加载位图。您不能期望任何 OpenGL 句柄在活动恢复后仍然有效。

可以把它想象成笔记本电脑从休眠状态出来的例子。尽管所有内存都已恢复,但您不能指望任何打开的套接字仍然有一个真正的活动连接。

我是安卓新手,如有错误请指正。

于 2012-11-23T15:07:05.773 回答