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();
        }
    }
}

そして、それはクラッシュします。

どうして??OK、GLThread での例外の原因は次のとおりです。

java.lang.IllegalArgumentException: ビットマップがリサイクルされています...

元のアクティビティの 2 倍以上を起動すると、これが原因で、またはメモリの使用量が原因でアプリケーションがクラッシュし、これらの変更をすべて元に戻すか、これをどうするかがわからないため、この面倒なことを試しました。

このビットマップまたは別のアプリケーション アクティビティによって、メモリ内に保持して使用できるようにする良い方法はありますか?

どうか、あなたのアドバイスが必要です。

前もって感謝します。

4

2 に答える 2

2

リソースを手動で処理しないでください。アプリのサーフェスが壊れます。リソースを手動で処理することはできません。

リソースのリロードが心配で、API レベル 11 以降を使用している場合は、setPreserveEGLContextOnPause()を使用できます。テクスチャと FBO が保持されます。

API 11 以降を使用できない場合はGLSurfaceView()、アプリに移植できます。ICS から移植した自作の GLSurfaceViewを確認できます。

PS: 下手な英語で申し訳ありません。

于 2012-11-27T15:56:33.760 に答える
0

いいえ。Android にすべてのリソースを処理させます。アクティビティが再開されたら、適切なイベントを処理し、ビットマップを再読み込みする必要があります。アクティビティが再開された後、OpenGL ハンドルがまだ有効であるとは期待できません。

休止状態から復帰したラップトップの例と考えてください。すべてのメモリが復元されましたが、開いているソケットにまだ実際にアクティブな接続があるとは期待できません。

私は Android 初心者なので、間違っていたら訂正してください。

于 2012-11-23T15:07:05.773 に答える