这是我在这里的第一篇文章。对不起,如果做得不好并提前感谢。
有些东西让我发疯。
我尝试绘制一些东西并在屏幕上慢慢显示。为此,我使用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) {
}
}
}
}
答案 0 :(得分:0)
您的代码是sleep()
主线程,也称为UI线程。这是你绝对不能做的事情,因为主线程负责处理所有"东西"在Android中:UI渲染,UI事件调度等。您可以阅读Android Developer网站上的Processes and Threads指南以获取更多信息。选择报价:
因此,Android的单线程模型只有两个规则:
不要阻止UI线程
- 醇>
不要从UI线程外部访问Android UI工具包
然后问题变成了,做如何在不睡眠主线程的情况下为视图设置动画?诀窍是告诉Android去做其他事情并在一段时间后回到你身边(重绘你)。每次绘制时,都会计算推进动画的程度。
执行此操作的一种(粗略)方法是使用postInvalidateDelayed(long)
,它完全相同:在给定的毫秒数后重绘您的视图。这不是一个精确的延迟,它会稍微波动,所以你不能假设确切地说有多少时间过去了。一种方法是将System.nanoTime()
存储在实例字段中,以便下次绘制时,您可以将差值调整为nanoTime()
的新读数。这个差异是经过了多少时间,因此告诉您应该更新动画状态的程度。如果您的动画总共应该持续1秒,并且自上次绘制场景以来已经过了100毫秒,则必须将所有内容提前10%。
Android提供a lot of utilities以简化此操作。