private void drawEnergyLine(Canvas canvas, int min, int max, Bitmap bmp,
int type) {
int bmpWidth = bmp.getWidth();
int bmpHeight = bmp.getHeight();
// 设置缩小比例
double scale = (float) min / (float) max;
// 计算出这次要缩小的比例
float scaleWidth = 1;
float scaleHeight = 1;
scaleWidth = (float) (scaleWidth * scale);
scaleHeight = (float) (1);
// 产生resize后的Bitmap对象
Matrix matrix = new Matrix();
matrix.postScale(scaleWidth, scaleHeight);
Bitmap resizeBmp = Bitmap.createBitmap(bmp, 0, 0, bmpWidth, bmpHeight,
matrix, true);
switch (type) {
case 0:
canvas.drawBitmap(resizeBmp, 10, 120, mPaint);// blood show 1
break;
case 1:
canvas.drawBitmap(resizeBmp, 690, 120, mPaint);// blood show 2
break;
case 2:
canvas.drawBitmap(resizeBmp, 10, 358, mPaint);// 黄能量小长条
break;
default:
break;
}
//resizeBmp.recycle();//这两句我添加了就画面就不能点了,所以不知道该如何释放
//System.gc();
}
////////////////////////////////
我在draw(canvas){//draw里调用这个函数
private void drawEnergyLine(Canvas canvas, 1, 5,bmp1,
0);//类似这样的调用
}
在后面的线程中
run(){
while(true){
try{
draw();
sleep(200);
}catch(Exception ex){
}}}
//提示的错误为:
2496-byte external allocation too large for this process
VM won't let us allocate 2496 bytes
java.lang.OutOfMemoryError:bitmap size exceeds VM budget
....图片内存如何释放,这个问题冒似提的人很多啊,可是到底原理是什么呢,我怎么知道一个图片不用了呢,说不定满足啥条件了又用了呢?

解决方案 »

  1.   

    控制图片的缩放,最好设一个阀值
    例如:
    // 缩放比例
    private float scale = 1.0f;...public boolean onKeyDown(int keyCode, KeyEvent event)
    {
    switch(keyCode)
    {
    // 放大
    case KeyEvent.KEYCODE_DPAD_UP:
         if (scale < 2.0) //阀值
         scale += 0.1;
         postInvalidate();
         break;...
      

  2.   

    你说的这个阀值好像我也有吧,最顶上有个scale
    但是这个scale却是动态的,我不是想实现一个动画效果,我是想让血条跟着血量不同而变化
      

  3.   

    是createBitmap方法导致OutofMemoryError么?
    正常情况下,创建Bitmap不会导致这种error,除非你无用的bitmap对象没有被及时销毁,内存占用太多。bitmap分两部分内存,对应着java对象部分的内存由垃圾回收机制处理,只要你不是无意识的保留它的引用就一切ok。对应着c部分的内存就是图片占用的内存,这张图片不使用的时候及时recycle掉。
    比如你用一个变量来保存bitmap,这个变量被另外一个bitmap重新赋值,那么之前的bitmap就要被清除掉,否则及时java内存清掉了,c内存还占用着。
      

  4.   

    参照这个google论坛上的帖子:
    http://code.google.com/p/android/issues/detail?id=8488
      

  5.   

    看我代码里面,我就是把resizeBitmap释放啦,却出问题了,显示后提示我lockCanvas错误。
    你说的变量又一次赋值我清楚了,但是这个变量我重新声明后再赋值呢,应该不会有问题了吧(用线程无限刷新)
    Bitmap bmp = new Bitmap();
    bmp.createBitmap.....这样呢,每次不都是个新的吗
    我注释掉的代码到底为啥不能添加呢
      

  6.   

    血条的个数为十个,且颜色不一,我有十个很小的PNG的图片。再说用进度条好像也不是解决问题的最有效的方法吧
      

  7.   

    这页面里楼主解决的方案连接无法访问,回答者也不少报怨结果不近人意
    有的说在onPause()里加gc(),但我的问题好像不是这种,我不是进程结束图片资源没释放
    而是进程运行中由于线程不断刷新内存占用不断的增大,归到底就是我注释的那句话,该怎么写,写在哪
      

  8.   

    你的线程里是个死循环while(true),每次都会调用draw方法
    draw方法又会调用drawEnergyLine方法,并且传了个Bitmap对象;在drawEnergyLine方法中,又根据传入的Bitmap对象重新生成了个Bitmap这两个Bitmap都没有及时recycle在产生resizeBitmap后,recycle掉传入的Bitmap,增加语句
    if(null != bmp) {
        bmp.recycle();
        bmp = null;
    }drawEnergyLine方法中的那个resizeBmp是不能recycle的,因为是draw(canvas)的内部方法,recycle了就无法显示了,建议LZ能不能该个方法实现,把drawEnergyLine方法实现改在draw方法里实现然后就是那个线程了
      

  9.   

    记得不用了就用Bitmap的recycle()方法回收。我之前也越到了这个问题。回收的时候图片要没有正在显示,否则回收没有效果。
      

  10.   

    LZ可以参见http://blog.csdn.net/zj_1395201/article/details/6640946,解决android加载图片OOM的问题!
      

  11.   

    不用申请临时Bitmap出来,因为有这个API:
    canvas.drawBitmap(mParchmentBmp , srcRect/*源大小*/, tmpDst/*目的大小*/, null);
      

  12.   

    不申请的话 mParchmentBmp这个你是怎么初始化的