如何使用单个ImageView显示不同的animationDrawable,在不同的时间启动,而不会触发错误的线程异常?"

时间:2016-01-29 17:23:03

标签: android animation

好的,我有一个我正在研究的游戏,我需要能够将不同的角色状态动画放到一个视图上。在这里,我有goblin_neutral和goblin_hit,作为2个动画列表,一个用于显示处于平静状态的敌人,另一个用于显示敌人被击中。两者都是可绘制文件夹中单独的.xml文件中的动画列表。

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:    

2 个答案:

答案 0 :(得分:0)

  

ViewRootImpl $ CalledFromWrongThreadException:

因为enemy ImageView对象是从TimerTaskTimerTask的运行访问,而是从UI线程在单独的线程上运行,但我们只能从UI线程更新或访问UI元素。

要使其正常工作,请使用runOnUiThread访问非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);
               ...
            }
         });
    }
};

答案 1 :(得分:0)

我接近这个的方法是使用Handler和Runnable。

在你的班级中,创建一个像这样的处理程序成员变量

Handler handler;

请注意您要按如下方式导入Handler:

import android.os.Handler;

同样创建一个像这样的可运行成员变量

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

在构造函数中,您可以初始化处理程序。

handler = new Handler();

因此,当您需要安排任务时,只需拨打

即可
handler.postDelayed(myRunnable, 600);
相关问题