Android 未调用 WebView evaluateJavaScript 回调
Android WebView evaluateJavaScript Callback is not being invoked
evaluateJavascript(String script, ValueCallback<String> resultCallback)
方法已添加到 SDK 19 中 Android 上的 WebView。
Android 文档引用:
If non-null, resultCallback will be invoked with any
result returned from that execution.
我正在使用如下所示的此方法,但不知何故我的回调未被调用。我可以从调试中看到调用了 evaluateJavascript()
,但是在 Android API 19、20 和 21 中没有调用回调。从 API 22 (LOLLIPOP_MR1) 开始,一切正常。
在 evaluateJavascript()
之前调用 webview.loadURL("")
使其适用于所有 API 级别。我想了解原因,如果有人可以阐明/分享有关此的任何链接,我将不胜感激。如果我能理解为什么,我想看看是否可以避免调用 loadURL()
。还有另一个不相关的问题使 loadURL()
成为一个不受欢迎的解决方案。
代码:
private void webViewTest() {
WebView webview = new WebView(this);
webview.getSettings().setJavaScriptEnabled(true);
Log.d("TEST", "BEFORE"); // LOGGED
// webview.loadUrl(""); // Enabling this makes it work on all Android versions
webview.evaluateJavascript("(function(){return 'test'})()", new ValueCallback<String>() {
@Override
public void onReceiveValue(String s) {
Log.d("TEST", "From JS: " + s); // NEVER LOGGED on API 19-21
}
});
Log.e("TEST", "AFTER"); // LOGGED
}
runOnUiThread(new Runnable() {
@Override
public void run() {
webViewTest();
}
});
找到此问题的示例
来自docs:
在当前显示页面的上下文中异步计算JavaScript。在 ContentViewCore
EvaluateJavascript
中检查渲染视图。看起来像集成在 19、20、21 中的 WebView
的特定版本 - RenderView
直到 loadUrl
被调用才创建。
我发现以下 FIX 可能相关:
它修改了 WebContentsAndorid EvaluateJavaScript 的本机实现,来自:
void WebContentsAndroid::EvaluateJavaScript(JNIEnv* env,
jobject obj,
jstring script,
jobject callback,
jboolean start_renderer) {
RenderViewHost* rvh = web_contents_->GetRenderViewHost();
DCHECK(rvh);
if (start_renderer && !rvh->IsRenderViewLive()) {
if (!static_cast<WebContentsImpl*>(web_contents_)->
CreateRenderViewForInitialEmptyDocument()) {
...
}
}
...
至:
void WebContentsAndroid::EvaluateJavaScript(JNIEnv* env,
jobject obj,
jstring script,
jobject callback) {
RenderViewHost* rvh = web_contents_->GetRenderViewHost();
DCHECK(rvh);
if (!rvh->IsRenderViewLive()) {
if (!static_cast<WebContentsImpl*>(web_contents_)->
CreateRenderViewForInitialEmptyDocument()) {
...
}
}
....
并且在 ContentViewCore
中有以下代码将 false
作为 start_renderer
传递:
public void evaluateJavaScript(String script, JavaScriptCallback callback) {
assert mWebContents != null;
mWebContents.evaluateJavaScript(script, callback, false);
}
这意味着在 WebView
上构建之前提到的对 evaluateJavaScript
的修复调用不会创建 RenderView
,因此 WebContext
无法处理 java 脚本执行。
因此,当您使用 loadUrl
时,您会强制创建渲染视图,并且所有内容都会按预期开始工作。
evaluateJavascript(String script, ValueCallback<String> resultCallback)
方法已添加到 SDK 19 中 Android 上的 WebView。
Android 文档引用:
If non-null, resultCallback will be invoked with any result returned from that execution.
我正在使用如下所示的此方法,但不知何故我的回调未被调用。我可以从调试中看到调用了 evaluateJavascript()
,但是在 Android API 19、20 和 21 中没有调用回调。从 API 22 (LOLLIPOP_MR1) 开始,一切正常。
在 evaluateJavascript()
之前调用 webview.loadURL("")
使其适用于所有 API 级别。我想了解原因,如果有人可以阐明/分享有关此的任何链接,我将不胜感激。如果我能理解为什么,我想看看是否可以避免调用 loadURL()
。还有另一个不相关的问题使 loadURL()
成为一个不受欢迎的解决方案。
代码:
private void webViewTest() {
WebView webview = new WebView(this);
webview.getSettings().setJavaScriptEnabled(true);
Log.d("TEST", "BEFORE"); // LOGGED
// webview.loadUrl(""); // Enabling this makes it work on all Android versions
webview.evaluateJavascript("(function(){return 'test'})()", new ValueCallback<String>() {
@Override
public void onReceiveValue(String s) {
Log.d("TEST", "From JS: " + s); // NEVER LOGGED on API 19-21
}
});
Log.e("TEST", "AFTER"); // LOGGED
}
runOnUiThread(new Runnable() {
@Override
public void run() {
webViewTest();
}
});
找到此问题的示例
来自docs:
在当前显示页面的上下文中异步计算JavaScript。在 ContentViewCore
EvaluateJavascript
中检查渲染视图。看起来像集成在 19、20、21 中的 WebView
的特定版本 - RenderView
直到 loadUrl
被调用才创建。
我发现以下 FIX 可能相关:
它修改了 WebContentsAndorid EvaluateJavaScript 的本机实现,来自:
void WebContentsAndroid::EvaluateJavaScript(JNIEnv* env,
jobject obj,
jstring script,
jobject callback,
jboolean start_renderer) {
RenderViewHost* rvh = web_contents_->GetRenderViewHost();
DCHECK(rvh);
if (start_renderer && !rvh->IsRenderViewLive()) {
if (!static_cast<WebContentsImpl*>(web_contents_)->
CreateRenderViewForInitialEmptyDocument()) {
...
}
}
...
至:
void WebContentsAndroid::EvaluateJavaScript(JNIEnv* env,
jobject obj,
jstring script,
jobject callback) {
RenderViewHost* rvh = web_contents_->GetRenderViewHost();
DCHECK(rvh);
if (!rvh->IsRenderViewLive()) {
if (!static_cast<WebContentsImpl*>(web_contents_)->
CreateRenderViewForInitialEmptyDocument()) {
...
}
}
....
并且在 ContentViewCore
中有以下代码将 false
作为 start_renderer
传递:
public void evaluateJavaScript(String script, JavaScriptCallback callback) {
assert mWebContents != null;
mWebContents.evaluateJavaScript(script, callback, false);
}
这意味着在 WebView
上构建之前提到的对 evaluateJavaScript
的修复调用不会创建 RenderView
,因此 WebContext
无法处理 java 脚本执行。
因此,当您使用 loadUrl
时,您会强制创建渲染视图,并且所有内容都会按预期开始工作。