Question

hi everyone hope you can help and thanks for looking -

i have a thread to run a coin spinning animation which is this

    public class MainActivity extends Activity {
static AnimationDrawable frameAnimation;

public boolean currentSpin = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    //is this where you want me to do it
    ImageView coinAnima = (ImageView) findViewById(R.id.imageView1);


    Button bt = (Button) findViewById(R.id.button1);
      bt.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
        spinCoin1();
        }
    });

}
//end of onCreate

public void spinCoin1(){
    coinAnima = (ImageView) findViewById(R.id.imageView1);
    coinAnima.setBackgroundResource(R.anim.coin_spin_heads); 

        new Thread(new Runnable() {
                    public void run() {
                        frameAnimation = (AnimationDrawable) coinAnima.getBackground();
                        frameAnimation.start();

                        try {
                            Thread.sleep(5000);
                          } catch (InterruptedException e) {
                            e.printStackTrace();
                          }    

                          frameAnimation.stop();

                    //end of run
                    }

        //starts the thread        
         }).start();

//end of method      
}
//end of class
}

it runs from an onclick of a button, when i click the button a second time it causes and error

which is

    03-10 23:33:28.804: E/AndroidRuntime(13689): FATAL EXCEPTION: Thread-12
03-10 23:33:28.804: E/AndroidRuntime(13689): android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
03-10 23:33:28.804: E/AndroidRuntime(13689):    at android.view.ViewRoot.checkThread(ViewRoot.java:2936)
03-10 23:33:28.804: E/AndroidRuntime(13689):    at android.view.ViewRoot.invalidateChild(ViewRoot.java:642)
03-10 23:33:28.804: E/AndroidRuntime(13689):    at android.view.ViewRoot.invalidateChildInParent(ViewRoot.java:668)
03-10 23:33:28.804: E/AndroidRuntime(13689):    at android.view.ViewGroup.invalidateChild(ViewGroup.java:2511)
03-10 23:33:28.804: E/AndroidRuntime(13689):    at android.view.View.invalidate(View.java:5272)
03-10 23:33:28.804: E/AndroidRuntime(13689):    at android.view.View.invalidateDrawable(View.java:7310)
03-10 23:33:28.804: E/AndroidRuntime(13689):    at android.widget.ImageView.invalidateDrawable(ImageView.java:176)
03-10 23:33:28.804: E/AndroidRuntime(13689):    at android.graphics.drawable.Drawable.invalidateSelf(Drawable.java:300)
03-10 23:33:28.804: E/AndroidRuntime(13689):    at android.graphics.drawable.DrawableContainer.selectDrawable(DrawableContainer.java:227)
03-10 23:33:28.804: E/AndroidRuntime(13689):    at android.graphics.drawable.AnimationDrawable.setFrame(AnimationDrawable.java:211)
03-10 23:33:28.804: E/AndroidRuntime(13689):    at android.graphics.drawable.AnimationDrawable.nextFrame(AnimationDrawable.java:203)
03-10 23:33:28.804: E/AndroidRuntime(13689):    at android.graphics.drawable.AnimationDrawable.run(AnimationDrawable.java:140)
03-10 23:33:28.804: E/AndroidRuntime(13689):    at android.graphics.drawable.AnimationDrawable.start(AnimationDrawable.java:107)
03-10 23:33:28.804: E/AndroidRuntime(13689):    at com.example.testanima.MainActivity$2.run(MainActivity.java:61)
03-10 23:33:28.804: E/AndroidRuntime(13689):    at java.lang.Thread.run(Thread.java:1019)

can anyone tell me a fix for this error and thanks again for looking

Était-ce utile?

La solution

You can't maniuplate gui elements in another thread. This is clearly stated in the docs.

You can update gui elements in your run() by using:

 public void run()
 ...
  runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            update gui elements
                        }
                 });
 ....

Also call clear() on your animation after your first animation has completed. Then you can use it more than once.

Autres conseils

You could create your coinAnima on the UI thread, by creating it when you create the rest of your view, and setting to a variable. Or you could use a Handler that uses the UI thread and get that to run your runnable. See this link for how to set up a handler on the UI thread http://developer.android.com/training/multiple-threads/communicate-ui.html

Try this,

public class MainActivity extends Activity {
static AnimationDrawable frameAnimation;

public boolean currentSpin = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    //is this where you want me to do it
    ImageView coinAnima = (ImageView) findViewById(R.id.imageView1);
    coinAnima.setBackgroundResource(R.anim.coin_spin_heads);
    frameAnimation = (AnimationDrawable) coinAnima.getBackground();

Button bt = (Button) findViewById(R.id.button1);
  bt.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
    spinCoin1();
    }
});

}
//end of onCreate

public void spinCoin1(){  

    new Thread(new Runnable() {
                public void run() {

                    frameAnimation.start();

                    try {
                        Thread.sleep(5000);
                      } catch (InterruptedException e) {
                        e.printStackTrace();
                      }    

                      frameAnimation.stop();

                //end of run
                }

    //starts the thread        
     }).start();

  //end of method      
  }
//end of class
}

And check this as well.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top