我试图通过重用runnable来避免垃圾创建。但是,我坚持如何正确实现这一点。
这是我的runnable包装类:
public class RotateRunnable implements Runnable {
Maze maze;
int i;
int steps;
int originalAngle;
int dir;
public RotateRunnable(Maze maze) {
this.maze = maze;
}
public void setRunnable(int i, int steps, int originalAngle, int dir) {
this.i = i;
this.steps = steps;
this.originalAngle = originalAngle;
this.dir = dir;
}
@Override
public void run() {
maze.setIsRotateRunning(true);
maze.setAngle(originalAngle + dir*(90*(i+1))/steps);
maze.rotateStep();
}
}
这是我实施它的地方:
private void smoothAnimateRotate(final int i, final int steps, final int originalAngle, final int dir) {
// handler.postDelayed(new Runnable() {
// @Override
// public void run() {
// isRotateRunning = true;
// angle = originalAngle + dir*(90*(i+1))/steps;
// rotateStep();
// }
// }, 25 * (i));
rotateRunnable.setRunnable(i, steps, originalAngle, dir);
handler.postDelayed(rotateRunnable, 25 * i);
}
注释掉的部分是工作代码。我遇到的问题是在调用rotateRunnable
之前在postDelay()
内设置变量。现在这不起作用,因为rotateRunnable
可能只执行最后设置的变量。这是因为smoothAnimateRotate()
在for循环中执行,它非常快速地更新变量。
如何将变量设置为run
方法的一部分,以便稍后执行run
时,它正在使用正确设置的变量执行?
答案 0 :(得分:2)
实际上,调用handler.postDelayed方法实际上是将消息推送到MessageQueue中,并使用runnable对象设置消息的回调。根据您的描述,您可以非常快速地在for循环中调用smoothAnimateRotate方法,这可能只需要很短的时间,甚至小于25ms,因此当messageQueue启动轮询消息并执行rotateRunnable时,只执行最后设置的变量。 / p>
你可以分配一个ArrayList对象来缓存所有变量,如下面的
public class RotateRunnable implements Runnable {
public static int index = 0;
public static ArrayList<RotateNode> rotateNodeList = new ArrayList<RotateNode>();
Maze maze;
int i;
int steps;
int originalAngle;
int dir;
public RotateRunnable(Maze maze) {
this.maze = maze;
}
public void setRunnable(int i, int steps, int originalAngle, int dir) {
RotateNode node = new RotateNode();
node.i = i % 100;
node.steps = steps;
node.originalAngle = originalAngle;
node.dir = dir;
rotateNodeList.add(i % 100, node);
}
@Override
public void run() {
RotateNode node = rotateNodeList.get(index % 100);
maze.setIsRotateRunning(true);
maze.setAngle(node.originalAngle + node.dir*(90*(node.i+1))/node.steps);
maze.rotateStep();
index ++;
}
}
public class RotateNode {
int i;
int steps;
int originalAngle;
int dir;
}
为了避免arraylist的大小无限增加,我假设每个圆圈的旋转动画是100步,你可以用每个圆的步数替换它。希望这适合你。