Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Animators may only be run on Looper threads Android

I'm trying to animate something when a task is completed. The problem here is I get this error message:

android.util.AndroidRuntimeException: Animators may only be run on Looper threads
   at android.animation.ValueAnimator.cancel(ValueAnimator.java:1004)
   at android.view.ViewPropertyAnimator.animatePropertyBy(ViewPropertyAnimator.java:965)
   at android.view.ViewPropertyAnimator.animateProperty(ViewPropertyAnimator.java:921)
   at android.view.ViewPropertyAnimator.alpha(ViewPropertyAnimator.java:735)
   at com.design.zaton.prototypei.MainActivity$1$1.run(MainActivity.java:93)
   at java.lang.Thread.run(Thread.java:761)

The app worked fine before with the same exact code but now it simply doesn't. I'm really confused.

Here's where the error happens:

new Thread(new Runnable() {
    @Override
    public void run() {
        final String s = getGiphyViews(String.valueOf(mEdit.getText()));
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                result.setText(s);
            }
        });

        loading.animate()
                .alpha(0)
                .setDuration(100);

        done.animate()
                .scaleY(1)
                .scaleX(1)
                .setDuration(300);
    }
}).start();

The error outlines the loading.animate() method.

Thanks in advance!

like image 963
Adrien Zier Avatar asked Jun 07 '16 21:06

Adrien Zier


3 Answers

runOnUiThread(new Runnable() {
            @Override
            public void run() {
                //Your code
            }
});

You have to execute the code in the UI Thread

like image 173
Davide Avatar answered Nov 09 '22 04:11

Davide


Looper threads are threads in Android that permanently loop (or until you cancel them). They work in conjunction with Handlers which will post and send messages to Looper threads. Animators use heavy use of Looper threads because they perform their actions in repeated cycles. This allows the animator to not block after you press "start" so you can continue to perform other actions.

To further complicate matters, you most likely are performing animations on View objects. These can only be run on the main UI thread (which happens to be the biggest Looper thread of them all). So, you can not run these animations on separate threads like you are trying.

like image 30
DeeV Avatar answered Nov 09 '22 03:11

DeeV


I think, there has been a solution for this using Handler. You can use postDelayed to minimal as 100 and run your animating tasks. In your case it would be:

new Handler().postDelayed(new Runnable() {
     @Override
     public void run() {
        final String s = getGiphyViews(String.valueOf(mEdit.getText()));
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                result.setText(s);
            }
        });

        loading.animate()
                .alpha(0)
                .setDuration(100);

        done.animate()
                .scaleY(1)
                .scaleX(1)
                .setDuration(300);
     }
}, 100);

I had this problem today and above work resolved the problem. I would love to hear from anyone if there is any problem with this method.

like image 27
Guruprasad J Rao Avatar answered Nov 09 '22 05:11

Guruprasad J Rao