1

I have this situation: there is the android/Kotlin app, which has the webview, which loads the Flutter web app from the Internet URL.

To be clear - this is not the case of having webview in the Flutter. Quite opposite - Flutter is used to build the web app, which is rendered within the Android webview.

We followed google instruction to create the webview interface: https://developer.android.com/guide/webapps/webview

I.e. Kotlin creates the Android object within the webview.

I can access this Javascript Android object from the Chrome Debug tools console, while debugging the webview.

I.e. the Android / Kotlin part is ok.

However the Android object is not found when being called from the Flutter web app. I crosschecked and Flutter web app can call the alert function.

Can someone give me the idea how to call the injected Android object?

Code for the Flutter web app:

void webViewExit() {
  print("User command: Exit webview.");

  try {
    js.context.callMethod("Android.onExitPressed");
  } catch (e) {
    print(e);
  }
}

Result in the chrome devtools console:

User command: Exit webview.
NoSuchMethodError: method not found: 'apply' on null

 ​ This works directly from within the devtools console attached to the webview:

Android.onExitPressed();

This also works (from the Flutter webview webapp):

void webViewExit() {
  print("User command: Exit webview.");

  try {
    // js.context.callMethod("Android.onBackPressed");
    js.context.callMethod("alert", ["Calling Alert works!"]);
  } catch (e) {
    print(e);
  }
}

1 Answer 1

1

I found the workaround:

I added the predefined function into the static index.html page of the Flutter web app:

index.html

  ...
  <script>
    if ('serviceWorker' in navigator) {
      window.addEventListener('flutter-first-frame', function () {
        navigator.serviceWorker.register('flutter_service_worker.js');
      });
    }

    // Added JS function starts here

    function onExitPressed() {
      console.log("Called onExitPressed in webview JS.");
      Android.onExitPressed();
    }
    // Added JS function ends here

  </script>
  <script src="main.dart.js" type="application/javascript"></script>
  ...

Now the call from Flutter web app works:

void webViewExit() {
  print("User command: Exit webview.");

  try {
    js.context.callMethod("Android.onExitPressed", []);
  } catch (e) {
    print(e);
  }
}

I assume the reason is that the Android object is injected after the dart's main.dart.js is loaded and initiated.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.