0

Ok, I have a game that I am working on, and I need to be able to put different character state animations onto a single view. Here I have goblin_neutral, and goblin_hit, as 2 animation lists, one to show an enemy in a calm state, and the other to show the enemy getting struck. Both are animation lists in separate .xml files in the drawable folder.

AnimationDrawable enemy_neutral_animation, enemy_hit_animation;
ImageView enemy, player;

//...after onCreate()
enemy = (ImageView)findViewById(R.id.ImageView2);
enemy.setBackgroundResource(R.drawable.goblin_neutral);
enemy_neutral_animation = (Animation)enemy.getBackground();
enemy_neutral.start();

//...now jump to the code that triggers a new animation
enemy.setBackgroundResource(R.drawable.goblin_hit);
enemy_hit_animation = (Animation)enemy.getBackground();
enemy_hit_animation.start();

// all of this works^^, as I can see the second animation displayed

// I use a timer to wait for the animation to finish
mTimer.schedule(timerTask, 600);

//mTask is where it stops everytime
timerTask = new TimerTask() {
        @Override
        public void run() {
            enemy.setBackgroundResource(R.drawable.goblin_anim_neutral);
            enemy_neutral = (AnimationDrawable)enemy.getBackground();
            enemy_neutral.start();

        }
    };
// I get a wrong thread exception
// E/AndroidRuntime: FATAL EXCEPTION: Timer-0                                               
ViewRootImpl$CalledFromWrongThreadException:    
Luke Goss
  • 31
  • 1
  • 1
  • 3
  • There are some ways to do it explained [here](http://stackoverflow.com/questions/2214735/android-animationdrawable-and-knowing-when-animation-ends) that might be useful so you don't have to rely on a `TimerTask`. – George Mulligan Jan 29 '16 at 17:33

2 Answers2

0

ViewRootImpl$CalledFromWrongThreadException:

Because enemy ImageView object is accessing from run of TimerTask and TimerTask run on separate Thread from UI Thread, but we can only update or access UI elements from UI Thread.

To get it work use runOnUiThread for accessing Views from non-ui Thread.like:

timerTask = new TimerTask() {
   @Override
    public void run() {
      runOnUiThread(new Runnable() {
            @Override
            public void run() {
                // access enemy here
               enemy.setBackgroundResource(R.drawable.goblin_anim_neutral);
               ...
            }
         });
    }
};
ρяσѕρєя K
  • 132,198
  • 53
  • 198
  • 213
0

The way I will approach this is to use a Handler and Runnable.

In your class, create a handler member variable like so

Handler handler;

Note you want to import Handler as follows:

import android.os.Handler;

Also create a runnable member variable like so

Runnable myRunnable = new Runnable() {
   @Override
   public void run() {
        enemy.setBackgroundResource(R.drawable.goblin_anim_neutral);
        enemy_neutral = (AnimationDrawable)enemy.getBackground();
        enemy_neutral.start();
   }
}

In your constructor, you could initialise the handler.

handler = new Handler();

So, when you need to schedule the task, you simply call

handler.postDelayed(myRunnable, 600);
Dee
  • 573
  • 1
  • 4
  • 10