Приложение зависает или блокируется через некоторое время перерисовки пользовательского представления - PullRequest
0 голосов
/ 22 апреля 2019

Я написал собственное представление, которое рисует график, и заставляю его перерисовывать, используя invalidate каждые 20 мс.Очень редко, через некоторое время приложение перестает отвечать на входные данные.График будет продолжать рисоваться, и кнопки будут переключаться на нажатие при нажатии, но они не будут вызывать метод onclick.На этом этапе, если я выйду из приложения, я не смогу открыть его снова, пока не убью его.

Я предполагаю, что это из-за перерисовки, потому что уменьшение таймера перерисовки до каждых 100 мс делает этопроблема исчезла (по крайней мере, из моих тестов), но, делая ее быстрее (10 мс), она становится более устойчивой.

Кажется, я ничего не могу найти в Интернете, и приложение не падает, поэтому я не получаю никакой ошибки в Android studio

Код для розыгрыша

@Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if(data.size() == 0) {
            DrawNoData(canvas);
            return;
        }
        int width = getWidth();
        int height = getHeight();
        int elWidth = (width - offset * 2) / data.size();
        int outline = 2;
        Iterator<Point> iterator = data.iterator();
        int i = 0;
        DecimalFormat df = new DecimalFormat("#0.#");
        textPaint.setTextAlign(Paint.Align.CENTER);
        if(data.size()>20) {
            textPaint.setTextSize(20);
        } else {
            textPaint.setTextSize(40);
        }
        while(iterator.hasNext()){
            Point next = iterator.next();
            int penX = offset + i * elWidth + elWidth/2;
            int penY = lerp(offset, height - offset, maxY == 0? 1 : 1 - next.y / maxY);
            canvas.drawRect(penX - elWidth/3, penY, penX + elWidth/3, height - offset, outlinePaint);
            canvas.drawRect(penX - elWidth/3 + outline, penY + outline, penX + elWidth/3 - outline, height - offset - outline, paint);

            //Draw text
            Rect bounds = new Rect();
            String text = df.format(next.x);
            textPaint.getTextBounds(text, 0, text.length(), bounds);
            int yPos = height - offset + bounds.height() * 2;
            canvas.drawText(text, penX, yPos, textPaint);
            i++;
        }
        DrawAxis(canvas);
        lerpData();
    }

    private void DrawNoData(Canvas canvas) {
        DrawAxis(canvas);
        textPaint.setTextAlign(Paint.Align.CENTER);
        textPaint.setTextSize(50);
        int xPos = (getWidth() / 2);
        int yPos = (int) ((getHeight() / 2) - ((textPaint.descent() + textPaint.ascent()) / 2)) ;
        canvas.drawText("Not enough data", xPos, yPos, textPaint);
    }

    private void DrawAxis(Canvas canvas) {

        DecimalFormat df = new DecimalFormat("#0.#");
        int nbLines = (int)(maxY / div);
        textPaint.setTextAlign(Paint.Align.RIGHT);
        if(nbLines>20) {
            textPaint.setTextSize(20);
        } else {
            textPaint.setTextSize(40);
        }
        for(int i = 0; i < nbLines; i++){
            Rect bounds = new Rect();
            String text = df.format(maxY - i * div);
            textPaint.getTextBounds(text, 0, text.length(), bounds);
            int xPos = offset - 20;
            int yPos = offset + (getHeight() - 2*offset) * i/nbLines - 5 ; // - bounds.height()
            canvas.drawText(text, xPos, yPos, textPaint);
            canvas.drawLine(0, offset + (getHeight() - 2*offset) * i/nbLines , getWidth(), offset + (getHeight() - 2*offset) * i/nbLines, gridPaint);
        }
        //canvas.drawLine(0, 0, getWidth(), 0, gridPaint);
        //canvas.drawLine(0, getHeight() - 1, getWidth(), getHeight() - 1, gridPaint);

        //Draw axis
        canvas.drawLine(offset, offset, offset, getHeight() - offset, axisPaint);
        canvas.drawLine(offset, getHeight() - offset, getWidth() - offset, getHeight() - offset, axisPaint);

        //Draw Y axis arrows
        Path path = new Path();
        path.moveTo(offset, offset);
        path.lineTo(offset + 10, offset);
        path.lineTo(offset, offset - 20);;
        path.lineTo(offset - 10, offset);
        path.lineTo(offset, offset);
        path.close();
        canvas.drawPath(path, axisPaint);

        //Draw X axis arrows
        path = new Path();
        path.moveTo(getWidth() - offset, getHeight() - offset);
        path.lineTo(getWidth() - offset, getHeight() - offset + 10);
        path.lineTo(getWidth() - offset + 20, getHeight() - offset);;
        path.lineTo(getWidth() - offset, getHeight() - offset - 10);
        path.lineTo(getWidth() - offset, getHeight() - offset);
        path.close();
        canvas.drawPath(path, axisPaint);
    }

Код для инициализации

private void init(@Nullable AttributeSet attrs) {
        data = new ArrayList<>();
        target = new ArrayList<>();
        paint = new Paint();
        paint.setColor(Color.BLUE);
        outlinePaint = new Paint();
        outlinePaint.setColor(Color.BLACK);
        gridPaint = new Paint();
        gridPaint.setColor(Color.LTGRAY);
        axisPaint = new Paint();
        axisPaint.setColor(Color.DKGRAY);
        textPaint = new Paint();
        textPaint.setColor(Color.GRAY);
        tick = false;
        Timer timer = new Timer();
        timer.scheduleAtFixedRate(new TimerTask(){
            @Override
            public void run(){
                invalidate();
            }
        },0,10);
    }

Вот видео о том, как это происходит

...