我的应用中存在问题。切换到LANDpace模式时,会调用setContentView()方法来显示钢琴键盘。钢琴键盘类扩展了Surfaceview,可以更好地显示按键。此SurfaceView类作为子项添加到我的横向布局:
RelativeLayout rootLayout = (RelativeLayout) findViewById(R.id.rootLayout);
RelativeLayout.LayoutParams relativeLayoutParams = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
relativeLayoutParams.addRule(RelativeLayout.BELOW, R.id.relativeLayoutLowerBar);
rootLayout.addView(keyboardSurfaceView, relativeLayoutParams);
在我的keyboardSurfaceView类中,使用BitmapFactory.decodeResource()方法在Bitmap数组中加载位图并保持位图直到应用程序被销毁。这非常有效。当我在纵向模式下切换时,我用setContentView()更改布局并删除keyboardSurfaceView:
if(keyboardSurfaceView != null && keyboardSurfaceView.getParent() != null)
((ViewGroup) keyboardSurfaceView.getParent()).removeView(keyboardSurfaceView);
位图加载一次。第一次切换到横向模式。我遇到了一个内存不足的错误,当swichtin从风景中的protrait高达10-20次,等等。当我在ddms视图中更新堆时,我可以看到,每当我在横向视图中从protrait视图切换时,堆大小就会增长到大约。 20mb,然后应用程序崩溃。我不知道为什么这种情况一直在发生。位图只加载一次,而不是每次都加载。
我也试过bitmap.recycle(); bitmap = null
但没有成功。还尝试使用Google最佳实践中描述的LRUCache类缓存位图。我还搜索了stackoverflow以找到解决问题的正确方法。仍然无法解决这个问题。我自己处理肖像/风景变化(使用onConfigurationChanged()方法覆盖)。将所有图像放在drawable-xhdpi中有点帮助。当改变方向时,堆大小和以前一样增长,但仍在增长。任何帮助将不胜感激......
例外:
02-13 22:44:09.419: E/dalvikvm-heap(935): 11448-byte external allocation too large for this process.
02-13 22:44:09.419: E/dalvikvm(935): Out of memory: Heap Size=16391KB, Allocated=13895KB, Bitmap Size=16394KB, Limit=32768KB
02-13 22:44:09.419: E/dalvikvm(935): Trim info: Footprint=16391KB, Allowed Footprint=16391KB, Trimmed=432KB
02-13 22:44:09.419: E/GraphicsJNI(935): VM won't let us allocate 11448 bytes
答案 0 :(得分:1)
这是有关如何有效处理位图的Android文档
http://developer.android.com/training/displaying-bitmaps/index.html
答案 1 :(得分:0)
好的第一次在我的surfaceView类中调用surfaceCreated时,我调用了这个方法,这个方法只被调用一次而不是每次我在屏幕上显示surfaceView时都会这样:
bitmapKeyboard = BitmapFactory.decodeResource(context.getResources(), R.drawable.keyboard);
bitmapGlowImages[0] = BitmapFactory.decodeResource(context.getResources(), R.drawable.keycdown);
bitmapGlowImages[1] = BitmapFactory.decodeResource(context.getResources(), R.drawable.blackkeydown);
bitmapGlowImages[2] = BitmapFactory.decodeResource(context.getResources(), R.drawable.keyddown);
bitmapGlowImages[3] = BitmapFactory.decodeResource(context.getResources(), R.drawable.blackkeydown);
bitmapGlowImages[4] = BitmapFactory.decodeResource(context.getResources(), R.drawable.keyedown);
bitmapGlowImages[5] = BitmapFactory.decodeResource(context.getResources(), R.drawable.keycdown);
bitmapGlowImages[6] = BitmapFactory.decodeResource(context.getResources(), R.drawable.blackkeydown);
bitmapGlowImages[7] = BitmapFactory.decodeResource(context.getResources(), R.drawable.keyddown);
bitmapGlowImages[8] = BitmapFactory.decodeResource(context.getResources(), R.drawable.blackkeydown);
bitmapGlowImages[9] = BitmapFactory.decodeResource(context.getResources(), R.drawable.keyddown);
bitmapGlowImages[10] = BitmapFactory.decodeResource(context.getResources(), R.drawable.blackkeydown);
bitmapGlowImages[11] = BitmapFactory.decodeResource(context.getResources(), R.drawable.keyedown);
在这个类中也运行一个单独的线程来绘制按下的键:canvas.drawBitmap(bitmap, null, destRect, null)
。最后,当调用onDestroy时,我的方法recycleBitmaps()被称为
public void recycleBitmaps() {
if(bitmapKeyboard != null) {
bitmapKeyboard.recycle();
bitmapKeyboard = null;
for(int i = 0; i < bitmapGlowImages.length; i++) {
bitmapGlowImages[i].recycle();
bitmapGlowImages[i] = null;
}
System.gc();
}
}
就是这样。每次在风景中,我都会将我的surfaceView添加到我的横向视图中的父视图中,并在纵向中将其再次删除,并加载我的纵向布局。我在onConfigurationChanged()
中进行此操作,因为我自己处理方向更改,因此每次更改设备方向时都不会销毁和创建应用。