自定义视图忽略延迟

时间:2017-10-08 05:23:00

标签: android

我想每秒更改一个绘制矩形的颜色。我有以下代码可以这样做。

private Runnable mRunnable;
private int mIndex;
...

public BlinkingView(Context context) {
    this(context, null);

    mRunnable = new Runnable() {
        @Override
        public void run() {
            long currentMillis = System.currentTimeMillis();
            Log.d("Tag", "Millis Dif -- " + (mIndex== 0 ? "GREEN" : "RED") + " :: " + (currentMillis - lastMillis));
            lastMillis = currentMillis;

            // Set the paint color to be drawn.
            mColoredRectPaint.setColor(mIndex++ % 2 == 1 ? Color.RED : Color.GREEN);

            // Update the view.
            invalidate();

            // Run again.
            postDelayed(mRunnable, 1000);
        }
    };

    post(mRunnable);
}

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);

    // Draw the colored rectangle
    canvas.drawRect(mLeft, mTop, mRight, mBottom, mColoredRectPaint);

    // Draw a boarder rectangle.
    canvas.drawRect(mStrokeLeft, mStrokeTop, mStrokeRight, mStrokeBottom, mOuterRectPaint);
}

但只有postDelayed的所有其他电话都被延迟了。我正在记录每次调用runnable的run方法之间的毫秒数。

D/Tag: DURATION -- GREEN :: 1000
D/Tag: DURATION -- RED :: 1
D/Tag: DURATION -- GREEN :: 1002
D/Tag: DURATION -- RED :: 3
D/Tag: DURATION -- GREEN :: 1001
D/Tag: DURATION -- RED :: 3
D/Tag: DURATION -- GREEN :: 1001
D/Tag: DURATION -- RED :: 2

所以其他所有电话都被推迟了。有什么想法吗?

3 个答案:

答案 0 :(得分:0)

使用Timer

private Timer myTimer;

myTimer = new Timer();
myTimer.schedule(new TimerTask()
{
    @Override
    public void run()
    {
            // Set the paint color to be drawn.
            mColoredRectPaint.setColor(mIndex++ % 2 == 1 ? Color.RED : Color.GREEN);

            // Update the view.
            invalidate();
    }
}, 0, 1000);

<强>更新

您还可以使用线程来管理您的计时器:

mThread=new Thread(new Runnable() {
        @Override
        public void run() {

            while (!Thread.currentThread().isInterrupted()) {

                // Set the paint color to be drawn.
                mColoredRectPaint.setColor(mIndex++ % 2 == 1 ? Color.RED : Color.GREEN);

                // Update the view.
                postInvalidate();

                switch (state){
                    case 1:
                        Thread.sleep(500);
                        break;
                    case 2:
                        Thread.sleep(1000);
                        break;
                    default:
                        Thread.sleep(3000);
                        break;
                }
            }
        }
    });
    mThread.start();

答案 1 :(得分:0)

问题不在于自定义视图。问题出在Handler上。我看到了你的帖子并尝试运行一个简单的代码:

final Handler handler = new Handler();
mRunnable = new Runnable() {
    @Override
    public void run() {
        long currentTime = System.currentTimeMillis();
        System.err.println(currentTime - lastTime);
        lastTime = currentTime;
        handler.postDelayed(mRunnable, 1000);
    }
};
handler.post(mRunnable);

令人惊讶的是,它也给出了相同的结果。

结论:如果您希望功能完全相同,请不要使用处理程序。您可能希望直接使用Thread

答案 2 :(得分:0)

请看下面我解释的代码会传递你的测试用例。

int tick = 0;
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
    @Override
    public void run() {
        tick++;
        if(tick%2==0) {
           handler.postDelayed(this, 500);
          // Set the paint color to be drawn.
           mColoredRectPaint.setColor(Color.RED);
        } else {
           mColoredRectPaint.setColor(Color.GREEN);
           handler.postDelayed(this, 1000);
        }
        // Update the view.
        invalidate();
    }
}, 1000)