Android WebView评估未调用JavaScript回调 [英] Android WebView evaluateJavaScript Callback is not being invoked
问题描述
evaluateJavascript(String script, ValueCallback<String> resultCallback)
方法已添加到SDK 19中Android上的WebView中.
evaluateJavascript(String script, ValueCallback<String> resultCallback)
method is added to WebView on Android in SDK 19.
Android文档引号:
Android documentation quotes:
如果非null,则resultCallback将与任何 该执行返回的结果.
If non-null, resultCallback will be invoked with any result returned from that execution.
我正在使用此方法,如下所示,但是不知何故我的回调没有被调用.从调试中我可以看到evaluateJavascript()
被调用,但是未在Android API 19、20& 21 .从API 22(LOLLIPOP_MR1)开始,一切正常.
I am using this method as shown below, but somehow my callback is not being invoked. I can see from debugging that the evaluateJavascript()
is called, but the call back is not being invoked in Android API 19, 20 & 21. From API 22 (LOLLIPOP_MR1) onwards, everything is working as expected.
在evaluateJavascript()
之前调用webview.loadURL("")
使其可以在所有API级别上使用.我想了解原因,如果有人可以阐明/分享与此有关的任何链接,我将不胜感激.如果我能理解为什么,我想看看是否可以避免调用loadURL()
.还有另一个不相关的问题使loadURL()
成为不受欢迎的解决方案.
Calling webview.loadURL("")
before evaluateJavascript()
makes it work on all the API levels. I want to understand why and would appreciate if somebody can shed some light / share any links about this. If I can understand why, I want to see if calling loadURL()
could be avoided. There is another unrelated problem which makes loadURL()
a non-preferable solution.
代码:
Code:
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();
}
});
请在 https://github.com/bashok001/TestApp 中找到此问题的示例.
Please find an example of this problem at https://github.com/bashok001/TestApp
推荐答案
Asynchronously evaluates JavaScript in the context of the currently displayed page. In ContentViewCore
EvaluateJavascript
checks for renderview. Looks like for that particular versions of WebView
integrated within 19,20,21 - the RenderView
is just not created until loadUrl
get called.
我发现以下 FIX 可能相关:
它已修改 WebContentsAndorid 的EvaluateJavaScript本地实现:
It's modify WebContentsAndorid native implementation of EvaluateJavaScript from :
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
:
And in ContentViewCore
there was following code which passing false
as start_renderer
:
public void evaluateJavaScript(String script, JavaScriptCallback callback) {
assert mWebContents != null;
mWebContents.evaluateJavaScript(script, callback, false);
}
这意味着在提到的对evaluateJavaScript
的修复调用之前构建的WebView
上,不会创建RenderView
,因此,WebContext
无法处理Java脚本执行.
因此,当您使用loadUrl
时,将强制创建渲染视图,并且所有视图都将按预期开始工作.
This mean that on WebView
built prior to mentioned fix calls to evaluateJavaScript
does not create RenderView
and as result WebContext
can't handle java script execution.
So when you use loadUrl
you force creation of render view and all starts working as expected.
这篇关于Android WebView评估未调用JavaScript回调的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!