• flutter开发实战-inappwebview实现flutter与Javascript方法调用


    flutter开发实战-inappwebview实现flutter与Javascript方法调用

    在使用inappwebview时候,需要flutter端与JS进行交互,调用相应的方法,在inappwebview中的JavaScript Handlers。
    在这里插入图片描述

    一、JavaScript Handlers

    要添加JavaScript Handlers,可以使用InAppWebViewController.addJavaScriptHandler方法,在该方法中定义handlerName和JavaScript端调用它时要调用的回调。回调可以返回要在JavaScript端发送的数据。如果您需要在加载网页后立即管理JavaScript处理程序,则应在创建InAppWebView时调用InAppWebViewController.addJavaScriptHandler。

    以下是如何注册JavaScript处理程序的示例:

    onWebViewCreated: (controller) {
      // register a JavaScript handler with name "myHandlerName"
      controller.addJavaScriptHandler(handlerName: 'myHandlerName', callback: (args) {
        // print arguments coming from the JavaScript side!
        print(args);
    
        // return data to the JavaScript side!
        return {
          'bar': 'bar_value', 'baz': 'baz_value'
        };
      });
    },
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    在JavaScript端,要执行回调处理程序并将数据发送到Flutter,您需要使用window.Flutter_inappwebview.callHandler(handlerName,…args)方法,其中handlerName是一个字符串,表示您正在调用的处理程序名称,args是可以发送到Fluter方面的可选参数。

    注意:

    如果相更换一个名字,我们可以更换一个名字来嵌套window.flutter_inappwebview

    window.myCustomObj = { callHandler: window.flutter_inappwebview.callHandler } and, then, you can use window.myCustomObj.callHandler

    此外,可以通过这种方式包装整个特定的处理代码:

    const myHandlerName = (…args) => window.flutter_inappwebview.callHandler(‘myHandlerName’, …args);

    然后调用myHandlerName();

    在Javascript端,如果需要调用callHandler,需要监听flatterInAppWebViewPlatformReady。可以使用在flatterInAppWebViewPlatformReady事件被分派时设置的全局标志变量,并在调用window.flutter_inappwebview.callHandler方法之前使用它。

    示例代码如下

    // execute inside the "flutterInAppWebViewPlatformReady" event listener
    window.addEventListener("flutterInAppWebViewPlatformReady", function(event) {
     const args = [1, true, ['bar', 5], {foo: 'baz'}];
     window.flutter_inappwebview.callHandler('myHandlerName', ...args);
    });
    
    // or using a global flag variable
    var isFlutterInAppWebViewReady = false;
    window.addEventListener("flutterInAppWebViewPlatformReady", function(event) {
     isFlutterInAppWebViewReady = true;
    });
    // then, somewhere in your code
    if (isFlutterInAppWebViewReady) {
     const args = [1, true, ['bar', 5], {foo: 'baz'}];
     window.flutter_inappwebview.callHandler('myHandlerName', ...args);
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    在flutter端,Flutter在执行注入方法时候,调用evaluateJavascript来执行callHandler,这个flutterInAppWebViewPlatformReady无需监听,因为这个flutterInAppWebViewPlatformReady已经Ready了。

    可以在onLoadStop中调用代码

    onLoadStop: (controller, url) async {
      await controller.evaluateJavascript(source: """
        const args = [1, true, ['bar', 5], {foo: 'baz'}];
        window.flutter_inappwebview.callHandler('myHandlerName', ...args);
      """);
    },
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    window.flutter_inappwebview.callHandler返回一个JavaScript Promise,该Promise可用于获取回调返回的json结果。在这种情况下,只需返回您想要发送的数据,它将使用dart:convert库中的jsonEncode自动进行json编码。

    一个简单的示例代码

    
    import 'dart:async';
    import 'dart:io';
    import 'package:flutter/material.dart';
    import 'package:flutter_inappwebview/flutter_inappwebview.dart';
    
    Future main() async {
      WidgetsFlutterBinding.ensureInitialized();
    
      if (Platform.isAndroid) {
        await AndroidInAppWebViewController.setWebContentsDebuggingEnabled(true);
      }
      
      runApp(new MyApp());
    }
    
    class MyApp extends StatefulWidget {
      @override
      _MyAppState createState() => new _MyAppState();
    }
    
    class _MyAppState extends State {
    
      InAppWebViewGroupOptions options = InAppWebViewGroupOptions(
          android: AndroidInAppWebViewOptions(
            useHybridComposition: true,
          ),);
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          home: Scaffold(
              appBar: AppBar(title: Text("JavaScript Handlers")),
              body: SafeArea(
                  child: Column(children: [
                    Expanded(
                      child: InAppWebView(
                        initialData: InAppWebViewInitialData(
                            data: """
    
    
        
            
            
        
        
            

    JavaScript Handlers

    """ ), initialOptions: options, onWebViewCreated: (controller) { controller.addJavaScriptHandler(handlerName: 'handlerFoo', callback: (args) { // return data to the JavaScript side! return { 'bar': 'bar_value', 'baz': 'baz_value' }; }); controller.addJavaScriptHandler(handlerName: 'handlerFooWithArgs', callback: (args) { print(args); // it will print: [1, true, [bar, 5], {foo: baz}, {bar: bar_value, baz: baz_value}] }); }, onConsoleMessage: (controller, consoleMessage) { print(consoleMessage); // it will print: {message: {"bar":"bar_value","baz":"baz_value"}, messageLevel: 1} }, ), ), ]))), ); } }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90

    二、监听自定义CustomEvent

    可以设置一个消息事件侦听器(与postMessage一起使用)或一个自定义事件侦听器。

    // message event listener
    window.addEventListener("message", (event) => {
      console.log(event.data);
    }, false);
    
    // or custom event listener
    window.addEventListener("myCustomEvent", (event) => {
      console.log(event.detail);
    }, false);
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    然后使用window.dispatch

    // using postMessage method
    window.postMessage({foo: 1, bar: false});
    
    // or dispatching a custom event
    const event = new CustomEvent("myCustomEvent", {
        detail: {foo: 1, bar: false}
    });
    window.dispatchEvent(event);
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    因此,可以在运行时使用InAppWebViewController.eevaluatteJavascript方法或在web应用程序内部设置这些事件侦听器,并使用相同的方法调度这些事件。

    例如:

    onLoadStop: (controller, url) async {
      await controller.evaluateJavascript(source: """
        window.addEventListener("myCustomEvent", (event) => {
          console.log(JSON.stringify(event.detail));
        }, false);
      """);
    
      await Future.delayed(Duration(seconds: 5));
    
      controller.evaluateJavascript(source: """
        const event = new CustomEvent("myCustomEvent", {
          detail: {foo: 1, bar: false}
        });
        window.dispatchEvent(event);
      """);
    },
    onConsoleMessage: (controller, consoleMessage) {
      print(consoleMessage);
      // it will print: {message: {"foo":1,"bar":false}, messageLevel: 1}
    },
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    三、小结

    flutter开发实战-inappwebview实现flutter与Javascript方法调用。描述可能不是特别准确,请见谅。

    学习记录,每天不停进步。

  • 相关阅读:
    leetcode_171Excel表列序号
    Linux RPM 构建
    Hive基础知识
    生命周期的使用
    手写编程语言-递归函数是如何实现的?
    计算机图像编码入门篇(上)
    《500强高管谈VE》-企业经营与VE活动
    MySQL(2)
    PaddleSeg分割框架解读[01] readme解读
    《位图BitMap - 基于java实现》
  • 原文地址:https://blog.csdn.net/gloryFlow/article/details/133643136