1

Android allows specifying a Javascript interface to act as a bridge between the webview and Android code. Similarly, iOS provides the UiWebView stringByEvaluatingJavaScriptFromString method that allows communicating with the underlying webview.

But the issue is that once we build the flutter web app and say we include it as part of a web view in android , Then whenever communication needs to take place , there is some amount of code that we should write in both android side and javascript side manually.

Since editing javascript code generated from flutter web app build is impractical , we need a way to establish a communication channel on flutter side which will talk to the native side using the same type of javascript bridge above. This will be something similar to the method channels when using the flutter app on the native side directly.

So how would we inject or add our custom javascript code from inside flutter so that it will be added during compiling the js file ?

Natesh bhat
  • 12,274
  • 10
  • 84
  • 125
  • 1
    Have you seen [this](https://medium.com/@mksl/flutter-talking-to-a-webview-747da85a0815)? [This](https://medium.com/@yubarajpoudel708/flutter-webview-8116f090e9de)? Or [this](https://stackoverflow.com/questions/53689662/flutter-webview-two-way-communication)? – tomerpacific Mar 23 '20 at 06:28
  • @tomerpacific those articles are regarding embedding a web view inside the flutter app itself. I'm asking about using a web view in native Android which runs the flutter app. – Natesh bhat Mar 23 '20 at 07:47
  • 1
    Why would you want an android application to run a flutter application in a webview? That seems like a pretty complicated scenario. – tomerpacific Mar 23 '20 at 08:02

1 Answers1

0

You can create a webmessage channel on the android side (iOS has an equivalent).

There is a description of how to do it here:

How Do You Use WebMessagePort As An Alternative to addJavascriptInterface()?

A brief setup on the javascript side looks like this - you would need to implement this in dart html:

const channel = new MessageChannel();
var nativeJsPortOne = channel.port1;
var nativeJsPortTwo = channel.port2;
window.addEventListener('message', function(event) {
    if (event.data != 'capturePort') {
        nativeJsPortOne.postMessage(event.data)
    } else if (event.data == 'capturePort') {
        /* The following three lines form Android class 'WebViewCallBackDemo' capture the port and assign it to nativeJsPortTwo
        var destPort = arrayOf(nativeToJsPorts[1])
        nativeToJsPorts[0].setWebMessageCallback(nativeToJs!!)
        WebViewCompat.postWebMessage(webView, WebMessageCompat("capturePort", destPort), Uri.EMPTY) */
        if (event.ports[0] != null) {
            nativeJsPortTwo = event.ports[0]
        }
    }
}, false);

nativeJsPortOne.addEventListener('message', function(event) {
    alert(event.data);
}, false);

nativeJsPortTwo.addEventListener('message', function(event) {
    alert(event.data);
}, false);
nativeJsPortOne.start();
nativeJsPortTwo.start();

A similar solution for listening over using an eventlistener on the window in flutter web is below:

    window.onMessage.listen((onData) {
  print(onData.toString());

  MessageEvent messageEvent = onData;

  for (Property property in properties) {
    if (messageEvent.data["id"] == property.id) {

          });
    } else if (messageEvent.data["northEastLng"] != null) {
      print(messageEvent.data["northEastLat"]);

      if (double.parse(messageEvent.data["northEastLat"]) == bounds.northEast.lat && double.parse(messageEvent.data["northEastLng"]) == bounds.northEast.lng){
        return;
      }

      LatLng southWest = new LatLng(double.parse(messageEvent.data["southWestLat"]), double.parse(messageEvent.data["southWestLng"]));
      LatLng northEast = new LatLng(double.parse(messageEvent.data["northEastLat"]), double.parse(messageEvent.data["northEastLng"]));
      LatLngBounds incomingBounds = new LatLngBounds(southWest, northEast);
      if (incomingBounds == bounds) {
        return;
      }
      bounds = incomingBounds;
      _propertyListPresenter.filterBounds(bounds);
    }
  }
});
dazza5000
  • 7,075
  • 9
  • 44
  • 89