Android调用js的问题
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android调用js的问题相关的知识,希望对你有一定的参考价值。
请问android直接webview.loadUrl("javascript:js()")
js()的方法会执行嘛?
还是要弄个button出发js()
一 Android部分:
布局代码:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:focusable="true" android:focusableInTouchMode="true" android:orientation="vertical" android:padding="8dp" tools:context=".MainActivity"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content"> <EditText android:id="@+id/input_et" android:layout_width="0dp" android:layout_height="wrap_content" android:singleLine="true" android:layout_weight="1" android:hint="请输入信息" /> <Button android:text="Java调用JS" android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="sendInfoToJs" /> </LinearLayout> <WebView android:id="@+id/webView" android:layout_width="match_parent" android:layout_height="match_parent" /> </LinearLayout>
Activity代码:
public class MainActivity extends AppCompatActivity private WebView webView; @Override protected void onCreate(Bundle savedInstanceState) super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); webView = (WebView) findViewById(R.id.webView); webView.setVerticalScrollbarOverlay(true); //设置WebView支持JavaScript webView.getSettings().setJavaScriptEnabled(true); webView.loadUrl("file:///android_asset/webview.html"); //在js中调用本地java方法 webView.addJavascriptInterface(new JsInterface(this), "AndroidWebView"); // //添加客户端支持 webView.setWebChromeClient(new WebChromeClient()); private class JsInterface private Context mContext; public JsInterface(Context context) this.mContext = context; //在js中调用window.AndroidWebView.showInfoFromJs(name),便会触发此方法。 @JavascriptInterface public void showInfoFromJs(String name) Toast.makeText(mContext, name, Toast.LENGTH_SHORT).show(); //在java中调用js代码 public void sendInfoToJs(View view) String msg = ((EditText) findViewById(R.id.input_et)).getText().toString(); //调用js中的函数:showInfoFromJava(msg) webView.loadUrl("javascript:showInfoFromJava('" + msg + "')"); // webView.loadUrl("javascript:showInfoFromJava()");
二 网页代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Android WebView 与 Javascript 交互</title> </head> <body> <input type="button" value="分享" onclick="f1()"> <input type="text" id="show"/> </body> <script> function f1() AndroidWebView.showInfoFromJs("hello"); function showInfoFromJava(msg) document.getElementById("show").value=msg; alert(1); </script> </html>
注意: android 调用js代码可能会报错如下:
W/WebView(2088): java.lang.Throwable: A WebView method was called on thread 'JavaBridge'. All WebView methods must be called on the same thread.
解决办法:
webView.post(new Runnable() @Override public void run() webView.loadUrl("javascript:showInfoFromJava('" + msg + "')"); ); 参考技术B android怎样调用js文件里面的方法
如果多个线程同时访问一个集合,而其中至少一个线程修改了该集合,那么它必须 保持外部同步。这通常是通过对自然封装该集合的对象执行同步操作来完成的。如果不存在这样的对象,则应该使用 Collections.synchronizedSet 方法来“包装”集合。最好在创建时完成这一操作,以防止对 HashSet 实例进行意外的不同步访问:
Set s = Collections.synchronizedSet(new HashSet(...));
在 Flutter Web 中从 JS 调用 Dart 方法
【中文标题】在 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()
调用
【讨论】:
以上是关于Android调用js的问题的主要内容,如果未能解决你的问题,请参考以下文章