How to wait for a return value from executed JavaScript MAUI Android Threading

Wheelstring 145 Reputation points
2024-03-25T07:51:44.2733333+00:00

Hello all

I want get "right Threading way" when I wait for a JavaScript's result inside android webview (unfortunately function EvaluateJavaScriptAsync doesn't work :-(, cause I have own handler – need both directions from and to Javascript-C# include return values)

I have the functional c# code (see below) but code is quite slow and "not threading perfect"

I need REPLACE "while loop" and Thread.Sleep(100); with something "Threading Ingenious" (catch some message?..), I am just "Threading dummy user"

Thanks a lot Threading experts!

W

public class HybridWebViewHandler : ViewHandler<IHybridWebView, Android.Webkit.WebView>
{
...
	VirtualView.RequestEvaluateJavaScript += VirtualView_RequestEvaluateJavaScript;
...
        private void VirtualView_RequestEvaluateJavaScript(object sender, EvaluateJavaScriptAsyncRequest e)
        {
            EvaluateBack evaluateBack = new EvaluateBack();
            sync.Post((o) => PlatformView.EvaluateJavascript(e.Script, evaluateBack), null);
            while(!evaluateBack.Finished)
            {
                Thread.Sleep(100);
            }
            e.SetResult(evaluateBack.JavaScriptReturnValue);
        }

        public class EvaluateBack : Java.Lang.Object, IValueCallback
        {
            public bool Finished = false;
            private string _JavaScriptReturnValue = null;
            public string JavaScriptReturnValue
            {
                get { return _JavaScriptReturnValue; }
                set { _JavaScriptReturnValue = value; }
            }
            public void OnReceiveValue(Java.Lang.Object value)
            {
                _JavaScriptReturnValue = value.ToString();
                Finished = true;
            }
        }
...
}

Call:
EvaluateJavaScriptAsyncRequest request = new EvaluateJavaScriptAsyncRequest(JavaScriptCommand);
await Task.Run(() =>
{
    RequestEvaluateJavaScript?.Invoke(this, request);
});
return request.Task.Result;
.NET MAUI
.NET MAUI
A Microsoft open-source framework for building native device applications spanning mobile, tablet, and desktop.
2,869 questions
0 comments No comments
{count} votes

Accepted answer
  1. Bruce (SqlWork.com) 56,026 Reputation points
    2024-03-27T22:38:08.66+00:00

    I assume you are calling an async javascript routine. an async javascript function when called from c# just gets the promise object converted to a string. you need the javascript function to send a message to the c# on completion. you use the HybridWebView postMessage()

    myAsyncFunction(...).then(data => myPostMessage(data)); 
    

    the myPostMessage() should call .postMessage() which differs based on hosting o/s and which webview used. you will also need to implement a custom handler to receive the message. see:

    https://github.com/dotnet/maui/discussions/12009


3 additional answers

Sort by: Most helpful
  1. Yonglun Liu (Shanghai Wicresoft Co,.Ltd.) 35,546 Reputation points Microsoft Vendor
    2024-03-26T02:30:12.5433333+00:00

    Hello,

    WebView provides an out-of-the-box way to get the return value, and you could use EvaluateJavaScriptAsync instead of EvaluateJavaScript.

    Please refer to Invoke JavaScript for more detailed information.

    Best Regards,

    Alec Liu.


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.


  2. Wheelstring 145 Reputation points
    2024-03-27T20:09:43.87+00:00

    Hallo Yonglun

    thanks, I tried something with Send method (thanks for description of difference post/send), but I can't write down right syntax :-(

    but I have a some progress!:

    I changed Thread.Sleep(100); to Thread.Sleep(5); and it is acceptable solution now (speed quite good), but something inside of my soul says: it is not good clear solution :-)

    thanks and regards

    W

    0 comments No comments

  3. Wheelstring 145 Reputation points
    2024-03-28T11:32:01.83+00:00

    Hello Thread champions

    I found solution apparently without Thread.Sleep here:

    https://stackoverflow.com/questions/50998907/android-webview-blocking-evaluatejavascript

    but I don't know how to rewrite code from android studio to C# there is some keyword "final", and generated override method inside parameter passed to function etc..

    W

    0 comments No comments