Android:画布上的内存不足错误invalidate()

桑帕特·库玛(Sampath Kumar)
 10-18 17:38:41.400: E/dalvikvm-heap(24493): Out of memory on a 8294416-byte allocation.

我在屏幕中央绘制一个圆形图像,并将其划分为多边形等坐标。但是我的问题是,每当用户触摸坐标(有6个坐标可用)时,我都会将背景图像重新绘制到画布上。

它在最初的几次触摸中就可以正常工作,但是如果我触摸7至8次以上,则由于内存不足分配而崩溃,有时在创建画布的屏幕负载上也会崩溃。下面是canvas代码的实现。

public class CircleView extends View implements OnTouchListener{

private List<CircleViewBean> mMenuEntries = new ArrayList<CircleViewBean>();
private OnCellTouchListener mOnCellTouchListener = null;
public interface OnCellTouchListener {
    public void onTouch(Wedge cell);
}
private Shader mShader;

private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);

private float screen_density = getContext().getResources().getDisplayMetrics().density;


private int mMinSize = scalePX(60);             //Radius of inner ring size
private int mMaxSize = scalePX(170);                //Radius of outer ring size
private int mWedgeQty = 8;
private int xPosition = scalePX(120);           //Center X location of Radial Menu
private int yPosition = scalePX(120);           //Center Y location of Radial Menu
int touchIndex = -1;
private Wedge[] mWedges;

private RectF mViewRect = new RectF();


private int scalePX( int dp_size )
{
   int px_size = (int) (dp_size * screen_density + 0.5f);
   return px_size;
}


public CircleView(Context context) {
    this(context, null);
}

/**
 * Constructor used when this widget is created from a layout file.
 */
public CircleView(Context context, AttributeSet attrs) {
    super(context, attrs);
    HashMap<String, String> device = Constants.getDeviceDetails(getResources().getDisplayMetrics().heightPixels);
    int size = Integer.parseInt(device.get("circle_size"));
    this.xPosition = size==400? size/2 + 25 : size/2;
    this.yPosition = size==400? size/2 + 25 : size/2;
    Log.d("yPosition", yPosition+"-"+xPosition);
    mMinSize = Integer.parseInt(device.get("in_arc"));
    mMaxSize = Integer.parseInt(device.get("out_arc"));
    setBackgroundResource(R.drawable.centre_wheel);
    determineWedges();

}

private void determineWedges() {
    int entriesQty = mMenuEntries.size();
    if ( entriesQty > 0) {
        mWedgeQty = entriesQty;

        float degSlice = 360 / mWedgeQty;
        float start_degSlice = 270 - (degSlice/2);
        //calculates where to put the images

        this.mWedges = new Wedge[mWedgeQty];

        double mid = 0, min = 0, max = 0;
        for(int i = 0; i < this.mWedges.length; i++) {
            this.mWedges[i] = new Wedge(xPosition, yPosition, mMinSize, mMaxSize, (i
                    * degSlice)+start_degSlice, degSlice, mMenuEntries.get(i).getIndex());

            mid = this.mWedges[i].midValue = normalizeAngle( ((i * degSlice) + start_degSlice + degSlice) / 2 );
            min = normalizeAngle( (i * degSlice) + start_degSlice );
            max = normalizeAngle( (i * degSlice) + start_degSlice + degSlice);

            this.mWedges[i].minValue = min;
            this.mWedges[i].midValue = mid;
            this.mWedges[i].maxValue = max;

            mViewRect.union( new RectF( mWedges[i].getWedgeRegion().getBounds() ) );
        }

        mShader = new RadialGradient(xPosition, yPosition, mMaxSize, new int[] { 0xff595756, 0xffCCC5C3, 0xf878280}, null, Shader.TileMode.MIRROR);
        invalidate();
    }
} 

@Override
public void onDraw(Canvas canvas) {

    canvas.scale(getWidth() / mViewRect.width(), getHeight() / mViewRect.width(), xPosition, yPosition);
    //Saving the canvas and later restoring it so only this image will be rotated.
    canvas.save(Canvas.MATRIX_SAVE_FLAG);

    for (int i = 0; i < mWedges.length; i++) {
        Wedge f = mWedges[i];
        mPaint.setColor(Color.TRANSPARENT);
        mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
        canvas.drawPath(f, mPaint);
    }

    canvas.restore();

    canvas.save();
    canvas.restore();

    mPaint.setShader( mShader );  
}


private double normalizeAngle(double angle) {
    if(angle >= 0) {
        while( angle > 360 ) {
            angle -= 360;
        }
    }
    else {
        while( angle < -360) {
            angle += 360;
        }
    }
    return angle;
}

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    // TODO Auto-generated method stub
    int wmode = MeasureSpec.getMode(widthMeasureSpec);
    int hmode = MeasureSpec.getMode(heightMeasureSpec);
    int wsize = MeasureSpec.getSize(widthMeasureSpec);
    int hsize = MeasureSpec.getSize(heightMeasureSpec);

    int width = (int)mViewRect.width();
    int height = (int) mViewRect.height();

    if (wmode == MeasureSpec.EXACTLY) {
        width = wsize;
    }
    if (hmode == MeasureSpec.EXACTLY) {
        height = hsize;
    }
    this.setMeasuredDimension(width, height);

    invalidate();

}

public class Wedge extends Path {
    private int x, y;
    private int InnerSize, OuterSize;
    private float StartArc;
    private float ArcWidth;
    private Region mWedgeRegion;
    private int index=0;
    public double minValue;
    public double midValue;
    public double maxValue;
    private Wedge(int x, int y, int InnerSize, int OuterSize, float StartArc, float ArcWidth, int category) {
        super();
        this.index = category;
        if (StartArc >= 360) {
            StartArc = StartArc-360;
        }

        minValue = midValue = maxValue = 0;
        mWedgeRegion = new Region();
        this.x = x; this.y = y;
        this.InnerSize = InnerSize;
        this.OuterSize = OuterSize;
        this.StartArc = StartArc;
        this.ArcWidth = ArcWidth;
        this.buildPath();
    }
    public int getCategoryIndex(){
        return this.index;
    }
    public String toString() {
        return minValue + "  " + midValue + "  " + maxValue;
    }
    /**
     * 
     * @return the bottom rect that will be used for intersection 
     */
    public Region getWedgeRegion() {
        return mWedgeRegion;
    }

    private void buildPath() {

        final RectF rect = new RectF();
        final RectF rect2 = new RectF();

        //Rectangles values
        rect.set(this.x-this.InnerSize, this.y-this.InnerSize, this.x+this.InnerSize, this.y+this.InnerSize);
        rect2.set(this.x-this.OuterSize, this.y-this.OuterSize, this.x+this.OuterSize, this.y+this.OuterSize);

        this.reset();
        //this.moveTo(100, 100);
        this.arcTo(rect2, StartArc, ArcWidth);
        this.arcTo(rect, StartArc+ArcWidth, -ArcWidth);

        this.close();

        mWedgeRegion.setPath( this, new Region(0,0,480,800) );
    }
}

public boolean addMenuEntry(CircleViewBean menuEntry) {
    mMenuEntries.add(menuEntry);
    determineWedges();
    return true;
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    Log.d("", "touch");
    if(event.getAction() == MotionEvent.ACTION_UP){
        if(mOnCellTouchListener!=null && touchIndex >-1){
            int i=0;
            for(Wedge day : mWedges) {
                if(day.getWedgeRegion().getBounds().contains((int)event.getX(), (int)event.getY()) && touchIndex==i) {
                    mOnCellTouchListener.onTouch(mWedges[touchIndex]);
                    break;
                }
                i++;
            }
        }
    }else if(event.getAction() == MotionEvent.ACTION_DOWN || event.getAction() == MotionEvent.ACTION_MOVE){
        int i=0;
        for(Wedge day : mWedges) {
            if(day.getWedgeRegion().getBounds().contains((int)event.getX(), (int)event.getY())) {
                touchIndex = i;
                setBackgroundResource(mMenuEntries.get(touchIndex).getIcon());
            }
            i++;
        }
        //invalidate();
    }
    return true;
}
public void setOnCellTouchListener(OnCellTouchListener p) {
    mOnCellTouchListener = p;
}

public boolean onTouch(View v, MotionEvent event) {
    return false;
}

}

桑帕特·库玛(Sampath Kumar)

我将此行放在清单文件的“应用程序”选项卡中

android:largeHeap="true"

这要求最低api级别11。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

内存不足错误:Android Studio上的Java堆内存

来自分类Dev

某些设备上的内存不足错误

来自分类Dev

Android Studio内存不足错误ViewFlipper

来自分类Dev

Android:内存不足错误StringBuilder

来自分类Dev

android位图中的内存不足错误

来自分类Dev

内存不足错误,Android ImageViews

来自分类Dev

Android:位图导致内存不足错误

来自分类Dev

使用Android位图的内存不足错误

来自分类Dev

Imageview中的Android内存不足错误

来自分类Dev

Android Java错误内存不足

来自分类Dev

Android Studio中的内存不足错误

来自分类Dev

Android Studio内存不足错误ViewFlipper

来自分类Dev

getDrawable()的内存不足错误

来自分类Dev

Fontconfig错误-“内存不足”

来自分类Dev

mysql内存不足错误

来自分类Dev

NetBeans内存不足错误

来自分类Dev

Fontconfig错误-“内存不足”

来自分类Dev

ConnectionQueueStatsProvider的内存不足错误

来自分类Dev

ShowCaseView内存不足错误

来自分类Dev

内存不足错误 imageview

来自分类Dev

在Ubuntu上执行Jest时出现内存不足错误

来自分类Dev

Mongodb构建/编译错误:Ubuntu上的内存不足

来自分类Dev

Android Studio内存不足

来自分类Dev

Android Realm:内存不足

来自分类Dev

Android内存不足位图

来自分类Dev

imageview android内存不足

来自分类Dev

内存不足android问题

来自分类Dev

Android内存不足位图

来自分类Dev

内存不足android项目