flatterwebview与Javascript的双向通信

flatterwebview与Javascript的双向通信,javascript,webview,dart,flutter,Javascript,Webview,Dart,Flutter,我有一个html文件,我正在使用flatter\u webview\u插件加载到flatter webview中。我使用evalJavascript在我的javascript代码中调用函数,意思是flatter(dart)->js。然而,我还需要一些方法将一些信息传回颤振(dart)层,意思是js->颤振(dart) 我试过使用 -webkit.messageHandlers.native -window.native 要支持这两种平台(Android、iOS),请检查JS中是否提供这些平台。但

我有一个html文件,我正在使用flatter\u webview\u插件加载到flatter webview中。我使用evalJavascript在我的javascript代码中调用函数,意思是flatter(dart)->js。然而,我还需要一些方法将一些信息传回颤振(dart)层,意思是js->颤振(dart)

我试过使用 -webkit.messageHandlers.native -window.native 要支持这两种平台(Android、iOS),请检查JS中是否提供这些平台。但是,这些都是未定义的。使用以下代码获取JS中本机处理程序的实例

typeof webkit !== 'undefined' ? webkit.messageHandlers.native : 
window.native;
即使我得到那个实例并使用它发布消息,也不知道如何在颤振(dart)层处理它。我可能需要使用平台频道。不确定,如果我在正确的方向上

有什么办法可以让我做到吗?我已经评估了interactive_webview插件。它在Android上运行良好。但是,它有快速版本控制的问题,不想再继续下去了


任何帮助都将不胜感激。

这里是一个从Javascript代码到Flatter的通信示例

在Flatter中,按如下方式构建您的网络视图:

WebView(
              initialUrl: url,
              javascriptMode: JavascriptMode.unrestricted,
              javascriptChannels: Set.from([
                JavascriptChannel(
                    name: 'Print',
                    onMessageReceived: (JavascriptMessage message) {
                      //This is where you receive message from 
                      //javascript code and handle in Flutter/Dart
                      //like here, the message is just being printed
                      //in Run/LogCat window of android studio
                      print(message.message);
                    })
              ]),
              onWebViewCreated: (WebViewController w) {
                webViewController = w;
              },
            )
在您的HTML文件中:

<script type='text/javascript'>
    Print.postMessage('Hello World being called from Javascript code');
</script>

Print.postMessage(“从Javascript代码调用Hello World”);
运行此代码时,您将能够在android studio的LogCat/run窗口中看到日志“Hello World正在从Javascript代码调用”。

您可以尝试我的插件(EDIT:它已重命名为)并使用
addJavaScriptHandler({@required String handlerName,@required JavaScriptHandlerCallback})
方法(请参阅更多)

下面是一个例子。 在颤振侧:

。。。
子:InAppWebView(
初始文件:“assets/index.html”,
initialHeaders:{},
initialOptions:InAppWebViewWidgetOptions(
inappwebview选项:inappwebview选项(
debuggingEnabled:true,
)
),
onWebViewCreated:(InAppWebViewController){
网络视图=控制器;
addJavaScriptHandler(handlerName:“mySum”,回调:(args){
//这里您将收到来自JavaScript端的所有参数
//那是一张单子
打印(“从JavaScript端:”);
打印(args);
返回参数reduce((当前,下一个)=>curr+next);
});
},
onLoadStart:(InAppWebViewController控制器,字符串url){
},
onLoadStop:(InAppWebViewController控制器,字符串url){
},
OnConsolleMessage:(InApp WebViewController控制器,ConsoleMessage ConsoleMessage){
打印(“控制台消息:${consoleMessage.message}”);
},
),
...
在JavaScript端(例如,资产文件夹中的本地文件
assets/index.html
):


应用浏览器中的颤振
...
...
//为了调用window.flatter\u inappwebview.callHandler(handlerName,…args)
//正确地说,您需要等待并监听AppWebViewPlatformReady中的JavaScript事件。
//一旦平台(Android或iOS)准备好处理callHandler方法,就会调度此事件。
window.addEventListener(“FlatterInAppWebViewPlatformReady”,函数(事件){
//调用名为“mySum”的颤振处理程序并传递一个或多个参数
appwebview.callHandler('mySum',12,2,50)。然后(函数(结果){
//从颤振侧获取结果。它将是数字64。
控制台日志(结果);
});
});
在Android Studio日志中,您将获得:

I/flutter (20436): From JavaScript side:
I/flutter (20436): [12, 2, 50]
I/flutter (20436): console message: 64

我想告诉您如何从Flatter WebView向JS发送消息:

  • 在JS代码中,您需要将您需要启动的函数绑定到窗口
  • const function=()=>alert('hello from JS');
    window.function=函数;
    
  • 在WebView小部件实现中的代码中,您需要像这样声明onWebViewCreated方法
  • WebView(
    onWebViewCreated:(WebViewController){},
    初始URL:'https://url.com',
    javascriptMode:javascriptMode.unrestricted,
    )
    
  • 类内小部件declare
    var\u webViewController
  • 类应用程序扩展状态{
    最终的webViewController;
    }
    
  • 在onWebViewCreated中编写以下代码
  • onWebViewCreated:(WebViewController){
    _webViewController=控制器;
    },
    
    然后可以运行如下代码:

    类应用程序扩展了无状态小部件{
    var_webViewController;
    @凌驾
    小部件构建(构建上下文){
    返回材料PP(
    标题:“颤振演示”,
    家:脚手架(
    正文:WebView(
    onWebViewCreated:(WebViewController控制器){
    _webViewController=控制器;
    },
    初始URL:'https://url.com',
    javascriptMode:javascriptMode.unrestricted,
    ),
    浮动操作按钮:浮动操作按钮(
    已按下:(){
    //当您单击此按钮时,您将运行js代码并看到警报
    _webViewController
    .evaluateJavascript('window.function()');
    },
    子:图标(Icons.add),
    背景颜色:Colors.green,
    ),
    ),
    );
    }
    }
    
    但是如果我们想将此
    \u webViewController
    实例共享给其他小部件,如drawer,该怎么办?
    在本例中,我决定实现
    单例模式
    ,并在其中存储
    \u webViewController
    实例。
    所以
    单身班

    类单例{
    WebViewController;
    静态最终单例_Singleton=新单例。_internal();
    静态单例获取实例=>\u单例;
    factory Singleton(WebViewController WebViewController){
    _singleton.webViewController=webViewController;
    返回单件;
    }
    Singleton._internal();
    }
    window.CHANNEL_NAME.postMessage('Hello from JS');
    
    import 'dart:async';
    import 'package:flutter/material.dart';
    import 'package:flutter_inappwebview/flutter_inappwebview.dart';
    
    Future main() async {
      WidgetsFlutterBinding.ensureInitialized();
      runApp(new MyApp());
    }
    
    class MyApp extends StatefulWidget {
      @override
      _MyAppState createState() => new _MyAppState();
    }
    
    class _MyAppState extends State<MyApp> {
      InAppWebViewController _webViewController;
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          home: Scaffold(
            appBar: AppBar(
              title: const Text('InAppWebView Example'),
            ),
            body: Container(
                child: Column(children: <Widget>[
              Expanded(
                child: InAppWebView(
                  initialData: InAppWebViewInitialData(data: """
    <!DOCTYPE html>
    <html lang="en">
        <head>
            <meta charset="UTF-8">
            <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
        </head>
        <body>
            <h1>JavaScript Handlers (Channels) TEST</h1>
            <button id='test' onclick="window.flutter_inappwebview.callHandler('testFunc');">Test</button>
            <button id='testargs' onclick="window.flutter_inappwebview.callHandler('testFuncArgs', 1);">Test with Args</button>
            <button id='testreturn' onclick="window.flutter_inappwebview.callHandler('testFuncReturn').then(function(result) { alert(result);});">Test Return</button>
        </body>
    </html>
                      """),
                  initialOptions: InAppWebViewGroupOptions(
                      crossPlatform: InAppWebViewOptions(
                    debuggingEnabled: true,
                  )),
                  onWebViewCreated: (InAppWebViewController controller) {
                    _webViewController = controller;
    
                    _webViewController.addJavaScriptHandler(
                        handlerName: 'testFunc',
                        callback: (args) {
                          print(args);
                        });
    
                    _webViewController.addJavaScriptHandler(
                        handlerName: 'testFuncArgs',
                        callback: (args) {
                          print(args);
                        });
    
                    _webViewController.addJavaScriptHandler(
                        handlerName: 'testFuncReturn',
                        callback: (args) {
                          print(args);
                          return '2';
                        });
                  },
                  onConsoleMessage: (controller, consoleMessage) {
                    print(consoleMessage);
                  },
                ),
              ),
            ])),
          ),
        );
      }
    }
    
     IconButton(
               icon: Icon(Icons.developer_mode),
               onPressed: () {
                 webviewController
                     .evalRawJavascript('window.myFunction()',
                         inGlobalContext: false)
                     .then((value) => print(value));
               },
             )      
    
    function myFunction() {
     alert("I am an alert box!");
     return 'working';
    }
    
    function submitClick() {
     var data = document.getElementById('data').value;
     SubmitCallback(data) //defined in flutter
    }
    
     WebViewX(
             javascriptMode: JavascriptMode.unrestricted,
             initialContent: '<h2> Loading </h2>',
             initialSourceType: SourceType.HTML,
             onWebViewCreated: (controller) {
               webviewController = controller;
               _loadHtmlFromAssets();
               webviewController.addListener(() {});
             },
             dartCallBacks: {
               DartCallback(
                 name: 'SubmitCallback',
                 callBack: (msg) {
                   ScaffoldMessenger.of(context).showSnackBar(
                       SnackBar(content: Text('Submitted $msg successfully')));
                 },
               ),
             },
           )