Reputation: 1303
I'm trying to animate 4 images in succession, switching the animation when I get a new GCM message that sends a Broadcast Intent. I'll show the code for the first 2, and what is going wrong. Basically between the two commands(case 0 vs case 1), I need to be able to stop the first runnable and then start the 2nd. I try to do that by setting
isRunning = false;
but that doesn't work. I'm thinking if I kept hacking away I may get this right, but I am wondering what the correct way to do it is.
public void startAnimatedBackground(Integer num) {
isRunning = false;
ImageSwitcher imageSwitcher = null;
aniIn = AnimationUtils.loadAnimation(this,
android.R.anim.fade_in);
aniOut = AnimationUtils.loadAnimation(this,
android.R.anim.fade_out);
aniIn.setDuration(500);
aniOut.setDuration(500);
switch (num) {
case 0:
imageSwitcher = (ImageSwitcher) findViewById(R.id.switcher_accept);
break;
case 1:
imageSwitcher = (ImageSwitcher) findViewById(R.id.switcher_on_way);
break;
default:
break;
}
imageSwitcher.setInAnimation(aniIn);
imageSwitcher.setOutAnimation(aniOut);
imageSwitcher.setFactory(this);
imageSwitcher.setImageResource(images[0]);
isRunning = true;
final Handler handler = new Handler();
final ImageSwitcher finalImageSwitcher = imageSwitcher;
Runnable runnable = new Runnable() {
@Override
public void run() {
if (isRunning) {
System.out.println("Running.."+finalImageSwitcher+index);
index++;
index = index % images.length;
finalImageSwitcher.setImageResource(images[index]);
handler.postDelayed(this, interval);
}
}
};
handler.postDelayed(runnable, interval);
}
This is what happens at first, and it is correct. I get a blinking image.
...app:id/switcher_accept}1 ...app:id/switcher_accept}0 ...app:id/switcher_accept}1 ...app:id/switcher_accept}0 ...app:id/switcher_accept}1
After case 2 runs, this is what the running process looks like. As you can see, both are running, and none of the expected behavior is happening. What I want is the 2nd(switcher_on_way) to run just like the first was before. I was hoping my isRunning=false; code would let this happen, but it obviously isn't.
...app:id/switcher_on_way}0 ...app:id/switcher_accept}1 ...app:id/switcher_on_way}0 ...app:id/switcher_accept}1 ...app:id/switcher_on_way}0 ...app:id/switcher_accept}1
Upvotes: 0
Views: 1815
Reputation: 7613
Your problem lies in this block:
Runnable runnable = new Runnable() {
@Override
public void run() {
if (isRunning) {
System.out.println("Running.."+finalImageSwitcher+index);
...
handler.postDelayed(this, interval);
}
}
};
handler.postDelayed(runnable, interval);
You tried to create a loop and control it via isRunning
variable. However, the problem is the condition is checked in the middle of the interval
when isRunning
is true
.
1: Start _isRunning=false______Check(isRunning)________Check(isRunning)
2: ___Start _isRunning=false___isRunning=true_______isRunning=true
and you need other approach, for example: create global handler
instead of local and then cancel the postDelayed
when you start a new animation.
Refer to: cancelling a handler.postdelayed process
or you can use wait
, synchronized
, and notify
.
Upvotes: 1