在 Flutter Web 中从 JS 调用 Dart 方法
Posted
技术标签:
【中文标题】在 Flutter Web 中从 JS 调用 Dart 方法【英文标题】:Call Dart method from JS in Flutter Web 【发布时间】:2021-04-02 01:14:59 【问题描述】:对于 Webview 相关功能,我使用方法通道通过原生 android 和 ios 代码打开 Webview,并且我正在其中打开一个网站,我正在从 JS 回调到移动平台中的原生代码。 对于 Android,我提供了一个从 JS 调用其方法的类, 它看起来像这样:
webView.settings.javascriptEnabled = true
webView.addJavascriptInterface(WebAppInterface(this), "nativeCommunicator")
webView.loadUrl("SOME_URL")
…
class WebAppInterface(private val mContext: Activity)
@JavascriptInterface
fun postMessage(text: String)
println("WebAppInterface.message($text)")
//send back to flutter
从 js 到我的代码的回调似乎很简单。
现在我正在尝试在 Flutter Web 中执行此操作 我通过调用打开了网站
import 'package:js/js.dart';
...
js.context.callMethod('open', 'SOME_URL', '_self');
效果很好,现在我正在尝试通过创建此类来获取回调
@JS()
library native_communicator;
import 'package:js/js.dart';
@JS('nativeCommunicator')
class NativeCommunicator
@JS('postMessage')
external static set _postMessage(void Function(String text) f);
@JS()
external static void postMessage();
void setJSCallbackFunction(void Function(String text) postMessageFunction)
NativeCommunicator._postMessage = allowInterop(postMessageFunction);
我正在调用 setJSCallbackFunction 并将我的函数作为参数传递,但它不断给我运行时错误 它找不到'postMessage',我尝试了其他一些导致找不到'nativeCommunicator'错误的方法, 谁能指出如何正确地做到这一点? 我需要从 js 中调用一个 dart 方法。
【问题讨论】:
【参考方案1】:我认为您正在从 dart:js
库中寻找 allowInterop
函数:https://api.flutter.dev/flutter/dart-js/dart-js-library.html
示例代码:
import 'dart:html';
import 'dart:js';
import 'package:js/js_util.dart';
String dartFunc(String str)
return 'Inside dartFunc: ' + str;
void main()
setProperty(window, 'dartFunc', allowInterop(dartFunc));
runApp(MyApp());
【讨论】:
它就在我的代码中。请检查一下,您尝试过并且有工作样品吗? 抱歉,没注意到。我已经用一些示例代码更新了答案。 js怎么调用? 它是在全局window
对象上定义的,所以你可以通过dartFunc
或window.dartFunc
来引用它【参考方案2】:
使 Dart 函数可从 JavaScript 调用
如果您将 Dart 函数作为参数传递给 JavaScript API,请使用 allowInterop()
或 allowInteropCaptureThis()
包装 Dart 函数。
要通过名称从 JavaScript 调用 Dart 函数,请使用带有 @JS()
注释的 setter。
示例:
@JS()
library callable_function;
import 'package:js/js.dart';
/// Allows assigning a function to be callable from `window.functionName()`
@JS('functionName')
external set _functionName(void Function() f);
void _someDartFunction()
print('Hello from Dart!');
void main()
_functionName = allowInterop(_someDartFunction);
// JavaScript code may now call `functionName()` or `window.functionName()`.
来自package:js
docs
变化 -
@JS()
library native_communicator;
import 'package:js/js.dart';
@JS('nativeCommunicator')
class NativeCommunicator
@JS('postMessage')
external static set _postMessage(void Function(String text) f);
// No need to do this as 'allowInterop()' will do the necessary.
//
// @JS()
// external static void postMessage();
//
//
void setJSCallbackFunction(void Function(String text) postMessageFunction)
NativeCommunicator._postMessage = allowInterop(postMessageFunction);
import 'path/to/setJSCallbackFunction-file';
void main()
setJSCallbackFunction(param);
调试步骤
-
寻找生成的js文件-
build/web/main.dart.js
尝试使用搜索来定位函数。 (这里,postMessage
)
如果你找不到它,那么你可能错过了一些注释或者可能没有在main()
中调用allowInterop()
如果您能够找到它但它不起作用,请检查您的 dart 函数并确保您传递了正确的参数。此外,请确保 dart.main.js
在范围内。
<script src"path/to/dart.main.js">
window.functionName(); // or functionName()
</script>
倾向于将js函数定义为顶层函数,可以用
window.functionName()
或functionName()
调用
【讨论】:
以上是关于在 Flutter Web 中从 JS 调用 Dart 方法的主要内容,如果未能解决你的问题,请参考以下文章
在 Flutter 中从 main() 调用 setState()
在 Flutter 中从 Firebase 读取数组 [重复]
如何在我的颤振应用程序中从 bing web search apiv7 获取图像