未调用 Android WebView 评估 JavaScript 回调

Ash*_*tti 5 java android webview chromium android-webview

evaluateJavascript(String script, ValueCallback<String> resultCallback) 方法在 SDK 19 中添加到 Android 上的 WebView。

Android 文档引用:

如果非空,则 resultCallback 将使用从该执行返回的任何结果调用。

我正在使用此方法,如下所示,但不知何故我的回调没有被调用。我可以从调试中看到evaluateJavascript()被调用,但在 Android API 19, 20 & 21 中没有调用回调。从 API 22 (LOLLIPOP_MR1) 开始,一切都按预期工作。

调用webview.loadURL("")beforeevaluateJavascript()使其适用于所有 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();
        }
    });
Run Code Online (Sandbox Code Playgroud)

请在https://github.com/bashok001/TestApp 上找到此问题的示例

j2k*_*2ko 4

来自文档:

在当前显示页面的上下文中异步计算 JavaScript 。检查ContentViewCore EvaluateJavascript渲染视图。看起来对于WebView19,20,21 内集成的特定版本 -只是在被调用RenderView之前才创建。loadUrl

我发现以下可能相关的修复:

它修改了EvaluateJavaScript 的WebContentsAndorid本机实现:

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()) {
         ... 
     }
   }
   ...
Run Code Online (Sandbox Code Playgroud)

到 :

 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()) {
         ...
        }
      }
   ....
Run Code Online (Sandbox Code Playgroud)

其中ContentViewCore有以下代码传递false为start_renderer:

public void evaluateJavaScript(String script, JavaScriptCallback callback) {
    assert mWebContents != null;
    mWebContents.evaluateJavaScript(script, callback, false);
}
Run Code Online (Sandbox Code Playgroud)

这意味着在WebView前面提到的修复调用之前构建时evaluateJavaScript不会创建RenderView,因此WebContext无法处理 java 脚本执行。因此,当您使用时,loadUrl您会强制创建渲染视图,并且所有内容都开始按预期工作。