5

I'm trying to play a gif using the Movie object and it requires me to call the invalidate() method. However whenever I call this method I get the following error:

android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.

How do I fix this and why is it happening

Ryan
  • 727
  • 2
  • 14
  • 31
  • post your code snippet – Anil Jul 31 '17 at 11:41
  • run the code snippet in UI thread which is causing issue.use runOnUiThread method – Usman Rana Jul 31 '17 at 11:43
  • 1
    Possible duplicate of [Android "Only the original thread that created a view hierarchy can touch its views."](https://stackoverflow.com/questions/5161951/android-only-the-original-thread-that-created-a-view-hierarchy-can-touch-its-vi) – Anand Singh Jul 31 '17 at 11:49

6 Answers6

13

Runs the specified action on the UI thread.

I would like to recommend read this site runOnUiThread

runOnUiThread(new Runnable() {
  @Override
  public void run() {
    // call the invalidate()
  }
});
Joshua Pinter
  • 45,245
  • 23
  • 243
  • 245
redAllocator
  • 725
  • 6
  • 12
3

try this

 final Handler handler=new Handler();
    new Thread(new Runnable() {
        @Override
        public void run() {
           //your code
            handler.post(new Runnable() {
                @Override
                public void run() {
                    invalidate()
                }
            });
        }
    }).start();
Azim Shaikh
  • 589
  • 6
  • 18
3

in case you need it in Kotlin:

val handler = Handler(Looper.getMainLooper())
    handler.post({
        invalidate()
    })
Pedro Gonzalez
  • 1,429
  • 2
  • 19
  • 30
2

In Android, only the Main thread (also called the UI thread) can update views. This is because in Android the UI toolkit s not thread safe.

When you try to update the UI from a worker thread Android throws this exception.

Make sure to update the UI from the Main thread.

Yossi Segev
  • 607
  • 5
  • 12
1

I know this is an older question and the answers here already work but I had an issue with just using Handler because by default android studio uses the wrong Handler object. I had to specify android.os.Handler ie:

final android.os.Handler handler=new android.os.Handler(Looper.getMainLooper());
    handler.post(new Runnable() {
        @Override
        public void run() {
            do_your_ui_stuff_here
            }
        });
Mark
  • 3,138
  • 5
  • 19
  • 36
0

There's actually a method in the Android SDK you can use to run invalidate() on the UI thread without having to make your own runnable or handler manually, see the official docs here.

public void postInvalidate ()

Cause an invalidate to happen on a subsequent cycle through the event loop. Use this to invalidate the View from a non-UI thread.

This method can be invoked from outside of the UI thread only when this View is attached to a window.

Community
  • 1
  • 1