davwillev
davwillev

Reputation: 83

"Animators may only be run on Looper threads" error when loading an image to ImageView from assets folder (Android)

I am trying to build some methods that allow me to load one .png image at a time from a local folder, using the image's name. I have chosen to load from the assets folder since the res folder does not load by image name. Having read around a fair few Q&As, I have produced the following method:

    private void setImage(String imageName) {
        String imageReference = String.format("%1$s/%2$s", "images", imageName);
        Context appContext = getContext().getApplicationContext();
        AssetManager assetManager = appContext.getAssets();
        // get input stream
        InputStream inputStream = null;
        try {
            inputStream = assetManager.open(imageReference);
        } catch (IOException e) {
            e.printStackTrace();
        }
        // load image as drawable
        Drawable drawable = null;
        drawable = Drawable.createFromStream(inputStream, null);
        // set image to ImageView
        imageView.setImageDrawable(drawable);
        try {
            inputStream .close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

...where "images" is a subdirectory within the assets folder. Using the debugger, I can see that the method is successfully picking up an image, but as soon as it hits the line of code imageView.setImageDrawable(drawable);, the emulator throws the following error: AndroidRuntimeException: Animators may only be run on Looper threads

I have tried to work out what this means, in terms of my usage, but have failed so far. Any help/advice gratefully received :)

EDIT: Here is my latest stacktrace, which (perculiarly) has changed slightly since I posted my question:

E/AndroidRuntime: FATAL EXCEPTION: Timer-3
    Process: com.example.spineapp.debug, PID: 10369
    android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
        at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:7753)
        at android.view.ViewRootImpl.requestLayout(ViewRootImpl.java:1225)
        at android.view.View.requestLayout(View.java:23093)
        at android.view.View.requestLayout(View.java:23093)
        at android.view.View.requestLayout(View.java:23093)
        at android.view.View.requestLayout(View.java:23093)
        at android.view.View.requestLayout(View.java:23093)
        at android.view.View.requestLayout(View.java:23093)
        at android.view.View.requestLayout(View.java:23093)
        at android.view.View.requestLayout(View.java:23093)
        at android.view.View.requestLayout(View.java:23093)
        at android.widget.ScrollView.requestLayout(ScrollView.java:1533)
        at android.view.View.requestLayout(View.java:23093)
        at android.view.View.requestLayout(View.java:23093)
        at android.view.View.requestLayout(View.java:23093)
        at android.widget.ImageView.setImageDrawable(ImageView.java:571)
        at android.support.v7.widget.AppCompatImageView.setImageDrawable(AppCompatImageView.java:100)
        at com.spineapp.LeftRightJudgementStepLayout.setImage(LeftRightJudgementStepLayout.java:583)
        at com.spineapp.LeftRightJudgementStepLayout.startQuestion(LeftRightJudgementStepLayout.java:521)
        at com.spineapp.LeftRightJudgementStepLayout.startNextQuestionOrFinish(LeftRightJudgementStepLayout.java:1031)
        at com.spineapp.LeftRightJudgementStepLayout$7.run(LeftRightJudgementStepLayout.java:482)
        at java.util.TimerThread.mainLoop(Timer.java:562)
        at java.util.TimerThread.run(Timer.java:512)

Upvotes: 0

Views: 953

Answers (1)

ashu
ashu

Reputation: 1846

You're probably calling setImageDrawable() from a non-UI thread.

Try scheduling setImageDrawable on the UI thread.

imageView.post(
// or inside an activity use
// runOnUiThread(
  new Runnable() {
    @Override
    public void run() {
      imageView.setImageDrawable(...);
    }
  }
);

https://developer.android.com/reference/android/view/View#post(java.lang.Runnable)

https://developer.android.com/reference/android/app/Activity#runOnUiThread(java.lang.Runnable)

Upvotes: 1

Related Questions