Android:位图内存不足错误

Android:位图内存不足错误,android,memory,bitmap,heap,Android,Memory,Bitmap,Heap,我面临以下问题:当我的应用程序被销毁并多次重新创建(例如通过锁定和解锁屏幕)时,它会崩溃,并出现以下错误: 02-01 19:24:12.000: E/AndroidRuntime(22362): java.lang.OutOfMemoryError: (Heap Size=62755KB, Allocated=55237KB) 02-01 19:24:12.000: E/AndroidRuntime(22362): at android.graphics.Bitmap.nativeCre

我面临以下问题:当我的应用程序被销毁并多次重新创建(例如通过锁定和解锁屏幕)时,它会崩溃,并出现以下错误:

02-01 19:24:12.000: E/AndroidRuntime(22362): java.lang.OutOfMemoryError: (Heap Size=62755KB, Allocated=55237KB)
02-01 19:24:12.000: E/AndroidRuntime(22362):    at android.graphics.Bitmap.nativeCreateScaledBitmap(Native Method)
02-01 19:24:12.000: E/AndroidRuntime(22362):    at android.graphics.Bitmap.createScaledBitmap(Bitmap.java:744)
现在,我已经读了好几篇关于这个错误以及如何修复它的帖子,但到目前为止,它们似乎都没有帮助。下面是我如何处理应用程序中的图像: 我的应用程序只有一个类似以下内容的活动:

public class MainActivity extends Activity {

static MenuView mv;

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    [...]
    mv = (MenuView) findViewById(R.id.menuview);
    mv.setOnClickListener(new KlickLauscher());
}

public void onDestroy() {
    super.onDestroy();
    mv.destroy(); 
    System.gc();
}
public class MenuView extends View {

MyBitmap button;

public MenuView(Context context, AttributeSet attrs) {
    super(context, attrs);
    initialize();
}

public void initialize() {
     button = new MyBitmap("R.drawable.bitmap1");
}

public void onDraw(Canvas c) {
    c.drawBitmap(button.getBmp(),0,0,mPaint);
}   

public void destroy() {
    button.destroy();
}
class MyBitmap {

Bitmap bmp;

 public MyBitmap(int r) {
  bmp = MyBitmap.createBmp(r);
 }

 public Bitmap getBmp() {
  return bmp;
 }

 static Bitmap createBmp(int r) {
  // Some irrelevant code
  return Bitmap.createScaledBitmap(BitmapFactory.decodeResource(mv.getContext().getResources(),r), width, height, true);
 }

 public void destroy() {
  bmp.recycle();
 }
}
菜单视图看起来有点像这样:

public class MainActivity extends Activity {

static MenuView mv;

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    [...]
    mv = (MenuView) findViewById(R.id.menuview);
    mv.setOnClickListener(new KlickLauscher());
}

public void onDestroy() {
    super.onDestroy();
    mv.destroy(); 
    System.gc();
}
public class MenuView extends View {

MyBitmap button;

public MenuView(Context context, AttributeSet attrs) {
    super(context, attrs);
    initialize();
}

public void initialize() {
     button = new MyBitmap("R.drawable.bitmap1");
}

public void onDraw(Canvas c) {
    c.drawBitmap(button.getBmp(),0,0,mPaint);
}   

public void destroy() {
    button.destroy();
}
class MyBitmap {

Bitmap bmp;

 public MyBitmap(int r) {
  bmp = MyBitmap.createBmp(r);
 }

 public Bitmap getBmp() {
  return bmp;
 }

 static Bitmap createBmp(int r) {
  // Some irrelevant code
  return Bitmap.createScaledBitmap(BitmapFactory.decodeResource(mv.getContext().getResources(),r), width, height, true);
 }

 public void destroy() {
  bmp.recycle();
 }
}
最后但并非最不重要的是,MyBitmap类如下所示:

public class MainActivity extends Activity {

static MenuView mv;

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    [...]
    mv = (MenuView) findViewById(R.id.menuview);
    mv.setOnClickListener(new KlickLauscher());
}

public void onDestroy() {
    super.onDestroy();
    mv.destroy(); 
    System.gc();
}
public class MenuView extends View {

MyBitmap button;

public MenuView(Context context, AttributeSet attrs) {
    super(context, attrs);
    initialize();
}

public void initialize() {
     button = new MyBitmap("R.drawable.bitmap1");
}

public void onDraw(Canvas c) {
    c.drawBitmap(button.getBmp(),0,0,mPaint);
}   

public void destroy() {
    button.destroy();
}
class MyBitmap {

Bitmap bmp;

 public MyBitmap(int r) {
  bmp = MyBitmap.createBmp(r);
 }

 public Bitmap getBmp() {
  return bmp;
 }

 static Bitmap createBmp(int r) {
  // Some irrelevant code
  return Bitmap.createScaledBitmap(BitmapFactory.decodeResource(mv.getContext().getResources(),r), width, height, true);
 }

 public void destroy() {
  bmp.recycle();
 }
}

我的应用程序中的每一个位图都是使用这个MyBitmap类实现的,当调用onDestroy()时,它们中的每一个都会被回收。长话短说:有人知道还有什么可能导致错误吗?

尝试减少位图的采样,并根据您的需要使用正确的位图格式,如所述

另外,我认为
createBmp
中的代码实际上创建了两个位图,因此您可以回收不使用的位图


为什么首先要缩放位图?您可以将
imageView
设置为缩放它。

onDestroy不保证被调用。尝试在onPause()中循环使用。我已经使用Log.e(…)来确定何时调用onDestroy,到目前为止,它总是在我锁定应用程序时被调用。另外,button.getBmp().isRecycled()返回true。好的,在这里查看答案。这个问题不相关,但答案可能是。谢谢你的链接!但是如何回收在CreateBBMP中创建的第二个位图呢?首先,我认为您不需要以这种方式缩放位图。其次,如果坚持这样做,只需引用旧位图(由decodeResource创建)和新位图(由createScaledBitmap创建)。缩放后,可以回收旧的。