0

In the java code(container) i have to get some values by calling some javascript functions, for this im using webView.evaluateJavascript, the problem is that i get the callback only when all the code had already been executed. Is there any way to handle this or any other better alternative?

this is the code:


String[] jsonStringTagResult = new String[1];

//trying to get the value returned by patrolTagToInvoke(tagid)
webView.evaluateJavascript("patrolTagToInvoke('"+tagId+"')", new ValueCallback<String>() {
    @Override
    public void onReceiveValue(String value) {
    jsonStringTagResult[0] = value;
    }
});

//the callback from js doesn't arrive in time so jsonStringTagResult will always be null
if (jsonStringTagResult[0] != null || !jsonStringTagResult[0].isEmpty()) {
3
  • Executing code between the application and the webview will always be async. What is it that you want to do? Because it seems like you need to refactor your logic to do so. Commented Feb 7 at 10:11
  • i need to get the value returned from the js function called, and use it in the following code, but when i try to do so, the code obviously run even if i still didn't get the callback, and when i receive it, the application stop. Commented Feb 7 at 10:25
  • Why not trigger your logic when the callback is received? Commented Feb 7 at 11:25

1 Answer 1

0
  • the asynchronous nature of evaluateJavascript. The callback you're passing to evaluateJavascript is not guaranteed to be called immediately after the JavaScript code has been executed. This is because the JavaScript code is executed in the context of the WebView, which means it's running on a different thread.

  • Add the necessary permissions to your AndroidManifest.xml file

  • First you create a Java class that will be used as the JavaScript interface

    public class WebAppInterface {
      private Context context;
    
      public WebAppInterface(Context context) {
        this.context = context;
      }
    
      @JavascriptInterface
      public void sendTagResult(String tagResult) {
        // Handle the tag result here
      }
    }
    
  • Then, add the JavaScript interface to your WebView

    webView.addJavascriptInterface(new WebAppInterface(this), "Android");
    
  • you can modify your JavaScript code to call the sendTagResult method when you have the result

    function patrolTagToInvoke(tagid) {
      // Your existing code here
      // When you have the result, call the sendTagResult method
      Android.sendTagResult(result);
    }
    
  • Finally, in your Java code, you can override the onJsPrompt method of your WebViewClient to handle the prompt from your JavaScript code

    webView.setWebViewClient(new WebViewClient() {
     @Override
     public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) {
         // Check if the message is the tag result
         if (message.startsWith("tagResult:")) {
             // Extract the tag result from the message
             String tagResult = message.substring("tagResult:".length());
             // Handle the tag result here
             // ...
             // Don't forget to call JsPromptResult.confirm to indicate that you've handled the prompt
             result.confirm("");
             // Return true to indicate that you've handled the prompt
             return true;
         }
         // If the message is not a tag result, return false to let the WebView handle the prompt
         return false;
      }
    });
    
  • Android Calling JavaScript functions in WebView : Android Calling JavaScript functions in WebView

  • Communication with WebView in Android : https://www.techyourchance.com/communication-webview-javascript-android/

Not the answer you're looking for? Browse other questions tagged or ask your own question.