Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/181.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android图形:低性能_Android_Performance_Graphics_Ondraw - Fatal编程技术网

Android图形:低性能

Android图形:低性能,android,performance,graphics,ondraw,Android,Performance,Graphics,Ondraw,我在做一个自定义的滑动控制。类似于音量控制盘,因此某些值会根据旋转方向增大或减小。 我对此有两个问题: 性能真的很低 垃圾收集器被触发了很多次 嗯,我肯定我做错了什么,所以请给我点颜色看看 我在2.1(eclaire)SDK上使用Android图形 这是我在活动中调用的视图的代码: public class DrawingView extends View { private Paint p; Bitmap bitmap; Context mContext; Canvas canvas; pr

我在做一个自定义的滑动控制。类似于音量控制盘,因此某些值会根据旋转方向增大或减小。 我对此有两个问题:

  • 性能真的很低
  • 垃圾收集器被触发了很多次
  • 嗯,我肯定我做错了什么,所以请给我点颜色看看

    我在2.1(eclaire)SDK上使用Android图形

    这是我在活动中调用的视图的代码:

    public class DrawingView extends View {
    
    private Paint p;
    Bitmap bitmap;
    Context mContext;
    Canvas canvas;
    private float sweepAngle;
    private int _height;
    private int _width;
    private float lastAngle;
    private int percent;
    
    public DrawingView(Context context) {
        super(context);
        WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        Display display = wm.getDefaultDisplay();
        this.set_Width(display.getWidth());
        this.set_Height(display.getHeight());
        this.setSweepAngle(10);
        mContext = context;
        p = new Paint();
        p.setAntiAlias(true);
    
    }
    
    protected int getAngleFromLocation(Point location){
        int finalAngle = (int) (Math.atan2(location.y - 200, location.x - 200) * (180 / Math.PI));
        return finalAngle;
    }
    
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        bitmap = Bitmap.createBitmap(canvas.getWidth(), canvas.getHeight(),Bitmap.Config.ARGB_8888);
        this.canvas = new Canvas(bitmap);
        RectF rectF = new RectF();
        rectF.set(20, 20, this.get_Widtt() - this.get_Widtt()/10, this.get_Widtt() - this.get_Widtt()/10);
        canvas.drawArc(rectF, 180, this.getSweepAngle(), true, p);
        //invalidate();
    }
    
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        double increment = 3.6;
        Point touchLocation = new Point();
        touchLocation.x = (int)event.getX();
        touchLocation.y = (int)event.getY();
        canvas.drawBitmap(bitmap = Bitmap.createBitmap(canvas.getWidth(),canvas.getHeight(),Bitmap.Config.ARGB_8888),event.getX(), event.getY(),null );
        switch (event.getAction())
        { 
            case MotionEvent.ACTION_DOWN: 
                lastAngle = this.getAngleFromLocation(touchLocation);
                System.out.println("ACTION_DOWN");
                break;
    
            case MotionEvent.ACTION_MOVE:
                System.out.println("ACTION_MOVE");
                int currentAngle = this.getAngleFromLocation(touchLocation);
                System.out.println("CURRENT ANGLE: " + currentAngle); 
                if (currentAngle > lastAngle || (currentAngle == 1 && lastAngle == 359)) {
                    percent += increment;
                } else if (currentAngle < lastAngle) {
                    percent -= increment;
                }
                if (percent > 360) {
                    percent = 360;
                } else if (percent < 0) {
                    percent = 0;
                }
                lastAngle = currentAngle;
                 this.setSweepAngle(percent);
                 //Write the label
                 //int realPercent = percent*100/360;
                System.out.println("PERCENT: "+percent); 
                break;
    
            case MotionEvent.ACTION_UP:
                break;
        }
        return true;
    }
    }
    
    公共类DrawingView扩展视图{
    私人涂料p;
    位图;
    语境;
    帆布;
    私人浮动扫掠角;
    私人室内高度;
    私有整数宽度;
    私人角度;
    私人机构占百分之几;
    公共绘图视图(上下文){
    超级(上下文);
    WindowManager wm=(WindowManager)context.getSystemService(context.WINDOW\u服务);
    Display Display=wm.getDefaultDisplay();
    这个.set_Width(display.getWidth());
    这个.set_Height(display.getHeight());
    这个角度(10);
    mContext=上下文;
    p=新油漆();
    p、 setAntiAlias(真);
    }
    受保护的int getAngleFromLocation(点位置){
    int finalAngle=(int)(Math.atan2(location.y-200,location.x-200)*(180/Math.PI));
    返回终局;
    }
    @凌驾
    受保护的void onDraw(画布){
    super.onDraw(帆布);
    bitmap=bitmap.createBitmap(canvas.getWidth()、canvas.getHeight()、bitmap.Config.ARGB_8888);
    this.canvas=新画布(位图);
    RectF RectF=新的RectF();
    rectF.set(20,20,this.get\u-Widtt()-this.get\u-Widtt()/10,this.get\u-Widtt()-this.get\u-Widtt()/10);
    drawArc(rectF,180,this.getSweepAngle(),true,p);
    //使无效();
    }
    @凌驾
    公共布尔onTouchEvent(运动事件){
    双增量=3.6;
    点接触位置=新点();
    touchLocation.x=(int)event.getX();
    touchLocation.y=(int)event.getY();
    drawBitmap(bitmap=bitmap.createBitmap(canvas.getWidth()、canvas.getHeight()、bitmap.Config.ARGB_8888)、event.getX()、event.getY()、null);
    开关(event.getAction())
    { 
    case MotionEvent.ACTION\u DOWN:
    lastAngle=this.getAngleFromLocation(触摸位置);
    System.out.println(“动作向下”);
    打破
    case MotionEvent.ACTION\u移动:
    System.out.println(“动作”);
    int currentAngle=this.getAngleFromLocation(触摸位置);
    System.out.println(“当前角度:+currentAngle”);
    如果(currentAngle>lastAngle | |(currentAngle==1&&lastAngle==359)){
    百分比+=增量;
    }else if(当前角度<最后角度){
    百分比-=增量;
    }
    如果(百分比>360){
    百分比=360;
    }否则,如果(百分比<0){
    百分比=0;
    }
    lastAngle=当前角度;
    这个角度(百分比);
    //写标签
    //int realPercent=百分比*100/360;
    系统输出打印项次(“百分比:“+百分比”);
    打破
    case MotionEvent.ACTION\u UP:
    打破
    }
    返回true;
    }
    }
    
    无需在每个帧上创建新位图。事实上,您应该尽量避免在onDraw()中分配任何对象

    试试这个:

    private RectF mRectF = new RectF();
    
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawColor(Color.BLACK);
        mRectF.set(20, 20, this.get_Widtt() - this.get_Widtt() / 10, this.get_Widtt() - this.get_Widtt() / 10);
        canvas.drawArc(rectF, 180, this.getSweepAngle(), true, p);
    }
    

    同时删除对onTouchEvent中canvas.drawBitmap()的调用。

    无需在每个帧上创建新位图。事实上,您应该尽量避免在onDraw()中分配任何对象

    试试这个:

    private RectF mRectF = new RectF();
    
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawColor(Color.BLACK);
        mRectF.set(20, 20, this.get_Widtt() - this.get_Widtt() / 10, this.get_Widtt() - this.get_Widtt() / 10);
        canvas.drawArc(rectF, 180, this.getSweepAngle(), true, p);
    }
    

    还要删除对onTouchEvent中canvas.drawBitmap()的调用。

    很可能是位图/画布创建花费了这么长时间,触发了这么多GC。尤其是在
    onDraw()
    期间,以及
    onTouchEvent()
    期间,您希望尽可能少地创建对象。有什么原因不能将其移动到一个单独的方法,该方法只调用一次并在每个帧中重用相同的位图?看起来您要传递给
    createBitmap()
    的值是静态的,所以这不应该是一个问题。

    很可能是位图/画布创建花费了这么长时间,触发了这么多GC。尤其是在
    onDraw()
    期间,以及
    onTouchEvent()
    期间,您希望尽可能少地创建对象。有什么原因不能将其移动到一个单独的方法,该方法只调用一次并在每个帧中重用相同的位图?您传递给
    createBitmap()
    的值看起来是静态的,因此不应该是问题