我正在制作 2 张图像的简单旋转动画,一张在另一张上(每张都有不同的速度)。我知道已经有一个动画 API,但我需要使用这个来代替。
它工作得很好,但有时动画会停止很短的时间然后继续,使其“跳跃”(停留在某些帧上比其他帧更多)。
为什么会发生?因为GC?我能做些什么来避免它?我打算做一些后台操作,所以它可能会变得更慢。
我知道使用 sleep() 并不意味着线程会在给定时间后立即唤醒,但这太多了,而且非常明显。
有什么技巧可以让它更流畅吗?也许使用更好的选择?
这是代码(执行它的视图):
public class AnimView extends SurfaceView implements SurfaceHolder.Callback
{
int _angle;
private final Bitmap _bitmap;
private final Paint _paint =new Paint();
private AnimationThread _animationThread;
private Matrix _matrix;
private int _width;
private int _height;
public AnimView(final Context context)
{
super(context);
_bitmap=BitmapFactory.decodeResource(getResources(),R.drawable.ic_launcher);
_paint.setAntiAlias(true);
getHolder().addCallback(this);
}
public AnimView(final Context context,final AttributeSet attrs)
{
super(context,attrs);
_bitmap=BitmapFactory.decodeResource(getResources(),R.drawable.ic_launcher);
_paint.setAntiAlias(true);
getHolder().addCallback(this);
}
public AnimView(final Context context,final AttributeSet attrs,final int defStyle)
{
super(context,attrs,defStyle);
_bitmap=BitmapFactory.decodeResource(getResources(),R.drawable.ic_launcher);
_paint.setAntiAlias(true);
getHolder().addCallback(this);
}
@Override
public void surfaceChanged(final SurfaceHolder holder,final int format,final int width,final int height)
{
_width=width;
_height=height;
}
@Override
public void surfaceCreated(final SurfaceHolder holder)
{
if(isInEditMode())
return;
_matrix=new Matrix();
setWillNotDraw(false);
_animationThread=new AnimationThread();
_animationThread.start();
}
@Override
public void surfaceDestroyed(final SurfaceHolder holder)
{
_animationThread.cancelAnimation();
}
@Override
protected void onDraw(final Canvas canvas)
{
if(isInEditMode())
{
canvas.drawColor(0xffff0000);
return;
}
_paint.setAntiAlias(true);
_matrix.reset();
_matrix.postScale(_width/_bitmap.getWidth(),_height/_bitmap.getHeight());
_matrix.postRotate(_angle,_width/2,_height/2);
canvas.drawBitmap(_bitmap,_matrix,_paint);
_matrix.reset();
_matrix.postScale(_width/_bitmap.getWidth(),_height/_bitmap.getHeight());
_matrix.postRotate(_angle*2,_width/2,_height/2);
canvas.drawBitmap(_bitmap,_matrix,_paint);
}
private class AnimationThread extends Thread
{
private boolean _isRunning =true;
public AnimationThread()
{}
public void cancelAnimation()
{
_isRunning=false;
}
@Override
public void run()
{
while(_isRunning)
{
postInvalidate();
refreshDrawableState();
try
{
sleep(5);
}
catch(final InterruptedException e)
{
e.printStackTrace();
}
_angle=(_angle+1)%360;
}
}
}
}