0

这是我在此的头一篇博文。抱歉,如果做得不好,请提前致谢。

有件事让我发疯。

我试着画一些东西并在屏幕上慢慢展示。为此,我使用 Thread.sleep,如代码所示。但它在每次迭代中显示了两个不同版本的画布。

谁能解释什么是错的?

我只想画点东西,几秒钟后画点别的东西。等等。

这是我的代码:

public class Vista extends SurfaceView implements Callback {
private Hilo hilo;
private SurfaceHolder sf;

class Hilo extends Thread {
    public boolean running;
    private Vista view;
    Canvas c = null;
    Bitmap btm = null;

    public Hilo(SurfaceHolder holder, Vista view) {
        sf = holder;
        btm = Bitmap.createBitmap(480, 800, Config.ARGB_8888);
        c = new Canvas(btm);
    }

    @Override
    public void run() {
        Paint paint = new Paint();
        paint.setStyle(Style.FILL_AND_STROKE);
        paint.setColor(Color.BLUE);

        int k = 0;
        while (running) {
            c = sf.lockCanvas();
            k+= 10;
            c.drawText(String.valueOf(k/10), k, 20, paint);
            sf.unlockCanvasAndPost(c);

          try {
              sleep(1000);
          } catch (InterruptedException e) {
              // TODO Auto-generated catch block
              e.printStackTrace();
          }
        }
    }
}

public Vista(Context context) {
    super(context);
    SurfaceHolder holder = getHolder();
    holder.addCallback(this);
    hilo = new Hilo(holder, this);
}

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
    // TODO Auto-generated method stub
}

@Override
public void surfaceCreated(SurfaceHolder holder) {
    hilo.running = true;
    hilo.start();
}

@Override
public void surfaceDestroyed(SurfaceHolder holder) {
    boolean retry = true;
    hilo.running = false;
    while (retry) {
        try {
            hilo.join();
            retry = false;
        } catch (InterruptedException e) {
        }
    }
}

}

4

1 回答 1

0

您的代码是sleep()主线程,也称为 UI 线程。这是你绝对不能做的事情,因为主线程负责处理 Android 中的所有“东西”:UI 渲染、UI 事件调度等。您可以阅读 Android 开发者网站上的进程和线程指南以获取更多信息。选择报价:

因此,Android 的单线程模型只有两条规则:

  1. 不要阻塞 UI 线程

  2. 不要从 UI 线程外部访问 Android UI 工具包

那么问题就变成了,如何在不休眠主线程的情况下为视图设置动画?诀窍是告诉 Android 去做其他事情,过一会儿再回到你身边(重绘你)。每次绘制时,您都会计算推进动画的程度。

一种(粗略的)方法是使用postInvalidateDelayed(long),它正是这样做的:在给定的毫秒数后重绘您的视图。这不是一个精确的延迟,它会有点波动,所以你不能假设这正是经过了多少时间。一种方法是将 存储System.nanoTime()在实例字段中,以便下次绘制时,您可以将差异用于nanoTime(). 这种差异是经过了多少时间,因此告诉您应该更新多少动画状态。如果您的动画应该总共持续 1 秒,并且自上次绘制场景以来已经过去了 100 毫秒,那么您必须将所有内容提前 10%。

Android 提供了许多实用程序来简化此操作。

于 2012-12-21T22:03:32.680 回答