5

We get error reports from Crashlytics affecting a sizable portion of our users (around 10% of them). It's a CalledFromWrongThreadException.

The problem is I don't know what's causing the issue and I don't have it myself. Here is the log:

Caused by android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
       at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:7282)
       at android.view.ViewRootImpl.invalidateChildInParent(ViewRootImpl.java:1197)
       at android.view.ViewGroup.invalidateChild(ViewGroup.java:5748)
       at android.view.View.invalidateInternal(View.java:15082)
       at android.view.View.invalidate(View.java:15046)
       at android.view.View.invalidate(View.java:15029)
       at android.view.SurfaceView$1.handleMessage(SurfaceView.java:142)
       at android.os.Handler.dispatchMessage(Handler.java:105)
       at android.os.Looper.loop(Looper.java:164)
       at com.unity3d.player.UnityPlayer$c.run(Unknown Source:20)

The com.unity3d.player.UnityPlayer$c.run(Unknown Source:20) is not really helpfull here as the origin is unknown, I guess it could come from a third party library (GVR SDK, Fabric...).

Does anyone have the same issue?

For reference we are using Unity version : 5.6.0f3 and the bug is reported only for Pixel and Pixel XL phones.

Quentin
  • 758
  • 9
  • 11

1 Answers1

0

I don't have all the details about your project, and the errors that cannot be reproduced in-house are the worst kind. Nevertheless, I'll try to give a few hints as to what's going on. Perhaps these hints can shed some light and help you figure out the root cause of error:

CalledFromWrongThreadException

On Android, a View can only be accessed from the thread that created it. This is actually true for other environments as well (WinForms, WPF, etc). This exception means that something is trying to access some UI element (SurfaceView) from the wrong thread.

com.unity3d.player.UnityPlayer$c.run

The stack trace originates from some custom Unity plumbing code. While this doesn't give a clue where this call comes from (in your C# code), it might mean the code came from C# (using AndroidJavaObject or AndroidJavaClass calls). Unity's scripting thread is not the same as Android's main thread, and so this makes sense together with the exception type you're getting.

As a test, i've used this code to simulate the same exception:

using (var actClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer")) 
{
    var activity = actClass.GetStatic<AndroidJavaObject>("currentActivity");

    // cause an exception to be thrown
    activity.Call("setContentView", 15);
}

This resulted in the following exception, which is very similar to the one you're getting (at least at its root).

E/ViewRootImpl(19244): com.test.crash.GameActivity : Only the original thread that created a view hierarchy can touch its views. E/ViewRootImpl(19244): java.lang.RuntimeException E/ViewRootImpl(19244): at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:7105) E/ViewRootImpl(19244): at android.view.ViewRootImpl.invalidateChildInParent(ViewRootImpl.java:1139) E/ViewRootImpl(19244): at android.view.ViewGroup.invalidateChild(ViewGroup.java:5254) E/ViewRootImpl(19244): at android.view.View.invalidateInternal(View.java:13669) E/ViewRootImpl(19244): at android.view.View.invalidate(View.java:13633) E/ViewRootImpl(19244): at android.view.View.onFocusChanged(View.java:6204) E/ViewRootImpl(19244): at android.view.View.clearFocusInternal(View.java:6089) E/ViewRootImpl(19244): at android.view.View.unFocus(View.java:6122) E/ViewRootImpl(19244): at android.view.ViewGroup.unFocus(ViewGroup.java:997) E/ViewRootImpl(19244): at android.view.ViewGroup.removeAllViewsInLayout(ViewGroup.java:4946) E/ViewRootImpl(19244): at android.view.ViewGroup.removeAllViews(ViewGroup.java:4905) E/ViewRootImpl(19244): at com.android.internal.policy.PhoneWindow.setContentView(PhoneWindow.java:410) E/ViewRootImpl(19244): at android.app.Activity.setContentView(Activity.java:2423) E/ViewRootImpl(19244): at com.unity3d.player.UnityPlayer.nativeRender(Native Method) E/ViewRootImpl(19244): at com.unity3d.player.UnityPlayer.a(Unknown Source) E/ViewRootImpl(19244): at com.unity3d.player.UnityPlayer$c$1.handleMessage(Unknown Source) E/ViewRootImpl(19244): at android.os.Handler.dispatchMessage(Handler.java:98) E/ViewRootImpl(19244): at android.os.Looper.loop(Looper.java:173) E/ViewRootImpl(19244): at com.unity3d.player.UnityPlayer$c.run(Unknown Source)

Summary

As i mentioned before, this only gives you a direction where to look. Hopefully you'll be able to find potential locations that can be the cause of this (probably plugin code). I'd be happy to further assist (in the comments, or feel free to contact me).

lysergic-acid
  • 19,570
  • 21
  • 109
  • 218