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メソッドを非常に迅速に呼び出しました。これには25ミリ秒未満の非常に短い時間しかかからない可能性があるため、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 に答える