Q:

Running multiple Runnables with Handler.postDelayed

I am trying to get a snippet of code to run periodically.
Here is my code:
int endTime = 52;
final double[] weights = new double[endTime];
for (int j = 0; j < endTime; j++) {
    final int k = j;
    newWeight = i.integrate(getCarbs(), getProt(), getFat(), newWeight,
            height, age, PAL, gender, 7);
    double percentChange = (newWeight - weight);
    percentChange = percentChange * 100 / weight;
    if(percentChange <-100){
        percentChange = -100;
    }
    weights[j] = percentChange;
    final DecimalFormat twoDForm = new DecimalFormat("0.00");
    final Handler h = new Handler();
    int time = 300*(j);
    Runnable r  = new Runnable() {
        public void run() {
            ((TextView) findViewById(R.id.weightGainNumbers))
                    .setText("Week:\t" + (k + 1) + "\nWeight Change:\t"
                        + twoDForm.format(weights[k]) + "%");
            animate(weights[Math.abs(k - 1)], weights[k], false);
        }
    };
    h.postDelayed(r, time);
}

The animation takes only 100 milliseconds.  however, when I run this, the application hangs, and only starts doing what it is supposed to around j = 15.  Does anybody know what's wrong here?

A:

You are performing unnecessary work in each iteration of your loop, like creating new DecimalFormats when you can simply reuse one. Also you only need one Handler and every View has a Handler already. All together this should run more smoothly.
First, set up some class variables:
final DecimalFormat twoDForm = new DecimalFormat("0.00");
TextView weightGainNumbers;
int weightGainIndex = 0;
final double[] weights;

Runnable r  = new Runnable() {
    public void run() {
        weightGainNumbers.setText("Week:\t" + (weightGainIndex + 1) + "\nWeight Change:\t"
                    + twoDForm.format(weights[weightGainIndex]) + "%");

        if(weightGainIndex > 0)
            animate(weights[Math.abs(weightGainIndex - 1)], weights[weightGainIndex], false);
        // This animation is a guess, but you get the idea...
        else
            animate(0, weights[weightGainIndex], false);

        weightGainIndex++;
        // Call the next animation or reset the index for next time
        if(weightGainIndex < weights.length)
            weightGainNumbers.postDelayed(r, 300);
        else
            weightGainIndex = 0;
    }
};

Next, initialize the weightGainNumbers TextView in onCreate().
Finally, use this:
int endTime = 52;
weights = new double[endTime];
for (int j = 0; j < endTime; j++) {
    newWeight = i.integrate(getCarbs(), getProt(), getFat(), newWeight,
            height, age, PAL, gender, 7);
    weights[j] = Math.max(percentChange * 100 / (newWeight - weight), -100);
}
weightGainNumbers.post(r);

Let me know if you have any specific questions.

