6

I have a custom android plugin for unity which opens a Webview activity. When I try to open the activity it crashes. When I try to initialise the WebView, below log statements appear from log cat.

Caused by: java.lang.IllegalStateException: Calling View methods on another thread than the UI thread.
at com.android.webview.chromium.WebViewChromium.createThreadException(WebViewChromium.java:252)
at com.android.webview.chromium.WebViewChromium.checkThread(WebViewChromium.java:267)  
at com.android.webview.chromium.WebViewChromium.init(WebViewChromium.java:163)
at android.webkit.WebView.<init>(WebView.java:661)
at android.webkit.WebView.<init>(WebView.java:596)
at android.webkit.WebView.<init>(WebView.java:579)
at android.webkit.WebView.<init>(WebView.java:566)
at android.webkit.WebView.<init>(WebView.java:556)
at com.vadrnet.unitysdk.MyWebViewClass.<init>(MyWebViewClass.java:31)
at com.vadrnet.unitysdk.WebViewActivity$1.run(WebViewActivity.java:207)
at android.app.Activity.runOnUiThread(Activity.java:5850)
at com.vadrnet.unitysdk.WebViewActivity.onCreate(WebViewActivity.java:205)
at android.app.Activity.performCreate(Activity.java:6582)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1113)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2532)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2667)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1494)
at android.os.Handler.dispatchMessage(Handler.java:111)
at android.os.Looper.loop(Looper.java:207)
at android.app.ActivityThread.main(ActivityThread.java:5776)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:789)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:679)

My code for starting the activity via Unity Script is

AndroidJavaClass unity = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
AndroidJavaObject currentActivity = unity.GetStatic<AndroidJavaObject>("currentActivity");
currentActivity.Call("runOnUiThread", new AndroidJavaRunnable(() =>
{
   AndroidJavaClass jc = new AndroidJavaClass("com.vadrnet.unitysdk.ManagerClass");
   AndroidJavaObject className = jc.CallStatic<AndroidJavaObject>("instance");
   className.Call("click", currentActivity, url);
 }));

and the Click function in the Plugin is

 public void click(Activity root, String url){
    Intent intent = new  Intent(root, WebViewActivity.class);
    intent.putExtra("url", url);
    root.startActivity(intent);
}

I couldn't get why the error occurs despite being opening the activity in the UI thread itself. Any help would be great.

Ravindra babu
  • 37,698
  • 11
  • 250
  • 211
shubham003
  • 703
  • 2
  • 9
  • 20

2 Answers2

1

you can use this bit of code may be it will be of help please check this before posting QA link

runOnUiThread(new Runnable() {
        @Override
    public void run() {
        // Code for WebView goes here
    }
});


// This code is BAD and will block the UI thread
webView.loadUrl("javascript:fn()");
while(result == null) {
  Thread.sleep(100);
}
thunderkill
  • 126
  • 5
0

The best solution by the web is

runOnUiThread(new Runnable() {
        @Override
        public void run() {

            // TODO Your code
        }
    });

When you do that look here so see how to use runOnUiThread currently

Example on how to use it in Unity (documentation link):

void Start()
    {
        AndroidJavaClass unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
        AndroidJavaObject activity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity");
        activity.Call("runOnUiThread", new AndroidJavaRunnable(runOnUiThread));
    }

    void runOnUiThread()
    {
        Debug.Log("I'm running on the Java UI thread!");
    }

Another Example on how to use it in Unity: (Link to source)

UnityPlayer.currentActivity.runOnUiThread(new Runnable() {
    public void run() {
           // Run in Thread...
    }
});

But you can also use

UserContrl1_LOadDataMethod()
{
    string name = "";
    if(myObject.InvokeRequired)
    {
        myObject.Invoke(new MethodInvoker(delegate { name = textbox1.text; }));
    }
    if(name == "MyName")
    {
        // do whatever
    }
}

For more info you can use This Link

General Grievance
  • 4,555
  • 31
  • 31
  • 45
amitklein
  • 1,302
  • 6
  • 23