您现在的位置是:首页 > 技术教程 正文

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

admin 阅读: 2024-03-29
后台-插件-广告管理-内容页头部广告(手机)

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方法调用。描述可能不是特别准确,请见谅。

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

标签:
声明

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

在线投稿:投稿 站长QQ:1888636

后台-插件-广告管理-内容页尾部广告(手机)
关注我们

扫一扫关注我们,了解最新精彩内容

搜索