0

我试图通过重用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稍后执行时,它使用正确设置的变量执行?

4

1 回答 1

2

实际上,调用 handler.postDelayed 方法实际上是将消息推送到 MessageQueue 中,并使用您的可运行对象设置消息的回调。根据你的描述,你在for循环中调用smoothAnimateRotate方法非常快,这可能只需要很短的时间,甚至不到25ms,所以当messageQueue开始轮询消息并执行rotateRunnable时,只执行最后设置的变量。

您可以分配一个 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步,你可以用你每圈的步数替换它。希望这对你有用。

于 2014-12-01T06:33:33.683 回答