2014-12-01 4 views
0

Я пытаюсь избежать создания мусора путем повторного использования runnable. Тем не менее, я зациклился на том, как правильно это реализовать.Повторное использование Runnable для handler.postDelayed()

Вот мой работоспособной класс обертки:

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() выполняется внутри цикла, который быстро обновляет переменные.

Как сделать настройку переменной части метода run так, чтобы после выполнения run она выполнялась с правильно заданными переменными?

ответ

2

Фактически метод call handler.postDelayed фактически нажимает сообщение в MessageQueue и устанавливает обратный вызов сообщения с помощью вашего рабочего объекта. Из вашего описания вы вызываете метод smoothAnimateRotate внутри цикла for очень быстро, это может занять очень короткое время, даже меньше, чем 25 мс, поэтому, когда messageQueue запускает голосовые сообщения и excute 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; 

}

избежать размера бесконечного increace Список_массивов, я предполагаю, что поворот анимации 100 шагов за круг, вы можете заменить его своими шагами на круг. Надеюсь, это сработает для вас.

Смежные вопросы