java - ART 在加载完成之前杀死 WebView

标签 java android webview

我正在尝试从使用 JavaScript 的网站检索 html。我的方法如下:

  • 创建一个 headless WebView(没有在 XML 中定义任何 View )并启用 JS。
  • 创建一个 JavaScriptInterface,其中包含加载完成时要调用的方法。
  • 重写我提供的WebClientView的onPageFinished方法。这里的代码注入(inject) JavaScript 来调用我在 JavaScriptInterface 中定义的方法,并将页面的 html 内容作为参数传递。

有趣的是,这段代码可以工作,但不一致。一次它会按预期工作,而下一次则什么也不会发生。我收到了各种奇怪的 logcat 消息,我怀疑其中之一可能是一个坏兆头: W/art: Attempt to remove non-JNI local reference, dumping thread 。 今天突然想到一个想法:也许有时我的 WebView 被杀死是因为运行时环境进行了优化(并且我的 WebView 没有链接到它的 XML View 对象)?

因此,我决定尝试在 XML 中创建一个 WebView 并使用相同的代码,而不是仅仅在代码中创建一个。现在,每次运行代码时,代码都会一致地工作,并且我不再收到那些线程转储日志消息。一旦我看到页面完成加载,代码就会被执行。

请注意,我注意到我引用的这个特定网站需要相对较长的时间来加载(长达几秒钟),并且 onPageFinished 被多次调用,除非是最后一次调用,否则使用未处理的 JS 传递 html。

所以,我的问题是:有什么方法可以防止 ART 在使用 headless 版本(或任何其他解决方法)时转储我的线程?我想过保留在 XML 中定义的 WebView,并将其可见性设置为 false,但这似乎是一个资源密集型解决方案。

我正在使用 Android 模拟器(尽管我使用物理设备也得到了相同的结果),目标 API 为 24,最低 API 15。

相关代码:

private void fetchHTML(View view, String url) {
    class JSInterface{
        @JavascriptInterface
        public void processHTML(String html){
            Log.d(LOG_TAG, html); // This bit of code sometimes gets executed, and sometimes does not
        }
    }
    //final WebView webView = (WebView) view.findViewById(R.id.webview);
    final WebView webView = new WebView(context);
    WebSettings settings = webView.getSettings();
    settings.setDomStorageEnabled(true);
    webView.addJavascriptInterface(new JSInterface(), "Android");
    webView.setWebChromeClient(new WebChromeClient());
    webView.setWebViewClient(new WebViewClient(){
        @Override
        public void onPageFinished(WebView view, String url) {
            super.onPageFinished(view, url);
            if(webView.getProgress() == 100){
                webView.loadUrl("javascript:window.Android.processHTML("
                        + "'<head>'+document.getElementsByTagName('html')[0].innerHTML+'</head>');");
            }
        }
    });

    settings.setJavaScriptEnabled(true);
    webView.loadUrl(url);
}

未正确执行时相关logcat:

07-15 17:16:27.616 17779-17779/com.michaelsvit.kolnoa W/System: ClassLoader referenced unknown path: /data/app/com.michaelsvit.kolnoa-2/lib/x86
07-15 17:16:28.214 17779-17779/com.michaelsvit.kolnoa W/System: ClassLoader referenced unknown path: /data/app/com.michaelsvit.kolnoa-2/lib/x86
07-15 17:16:28.267 17779-17779/com.michaelsvit.kolnoa W/art: Before Android 4.1, method android.graphics.PorterDuffColorFilter android.support.graphics.drawable.VectorDrawableCompat.updateTintFilter(android.graphics.PorterDuffColorFilter, android.content.res.ColorStateList, android.graphics.PorterDuff$Mode) would have incorrectly overridden the package-private method in android.graphics.drawable.Drawable
07-15 17:16:28.448 17779-17779/com.michaelsvit.kolnoa I/WebViewFactory: Loading com.android.webview version 44.0.2403.119 (code 246011910)
07-15 17:16:28.456 17779-17779/com.michaelsvit.kolnoa W/System: ClassLoader referenced unknown path: /system/app/webview/lib/x86
07-15 17:16:28.465 17779-17779/com.michaelsvit.kolnoa I/LibraryLoader: Time to load native libraries: 3 ms (timestamps 8656-8659)
07-15 17:16:28.465 17779-17779/com.michaelsvit.kolnoa I/LibraryLoader: Expected native library version number "",actual native library version number ""
07-15 17:16:28.470 17779-17779/com.michaelsvit.kolnoa V/WebViewChromiumFactoryProvider: Binding Chromium to main looper Looper (main, tid 1) {c4bffce}
07-15 17:16:28.470 17779-17779/com.michaelsvit.kolnoa I/LibraryLoader: Expected native library version number "",actual native library version number ""
07-15 17:16:28.470 17779-17779/com.michaelsvit.kolnoa I/chromium: [INFO:library_loader_hooks.cc(120)] Chromium logging enabled: level = 0, default verbosity = 0
07-15 17:16:28.476 17779-17779/com.michaelsvit.kolnoa I/BrowserStartupController: Initializing chromium process, singleProcess=true
07-15 17:16:28.479 17779-17779/com.michaelsvit.kolnoa W/art: Attempt to remove non-JNI local reference, dumping thread
07-15 17:16:28.479 17779-17779/com.michaelsvit.kolnoa E/SysUtils: ApplicationContext is null in ApplicationStatus
07-15 17:16:28.484 17779-17779/com.michaelsvit.kolnoa W/chromium: [WARNING:resource_bundle.cc(285)] locale_file_path.empty()
07-15 17:16:28.487 17779-17779/com.michaelsvit.kolnoa E/libEGL: validate_display:255 error 3008 (EGL_BAD_DISPLAY)
07-15 17:16:28.487 17779-17779/com.michaelsvit.kolnoa E/libEGL: validate_display:255 error 3008 (EGL_BAD_DISPLAY)

                                                                [ 07-15 17:16:28.488 17779:17779 D/         ]
                                                                HostConnection::get() New Host Connection established 0xac3edff0, tid 17779
07-15 17:16:28.525 17779-17779/com.michaelsvit.kolnoa E/eglCodecCommon: glUtilsParamSize: unknow param 0x00008d57
07-15 17:16:28.552 17779-17779/com.michaelsvit.kolnoa E/DataReductionProxySettingListener: No DRP key due to exception:java.lang.ClassNotFoundException: com.android.webview.chromium.Drp
07-15 17:16:28.568 17779-17831/com.michaelsvit.kolnoa W/AudioManagerAndroid: Requires BLUETOOTH permission
07-15 17:16:28.578 17779-17779/com.michaelsvit.kolnoa W/art: Attempt to remove non-JNI local reference, dumping thread
07-15 17:16:28.582 17779-17779/com.michaelsvit.kolnoa W/AwContents: onDetachedFromWindow called when already detached. Ignoring
07-15 17:16:28.584 17779-17779/com.michaelsvit.kolnoa W/art: Attempt to remove non-JNI local reference, dumping thread
07-15 17:16:28.585 17779-17779/com.michaelsvit.kolnoa W/AwContents: onDetachedFromWindow called when already detached. Ignoring
07-15 17:16:28.587 17779-17779/com.michaelsvit.kolnoa W/art: Attempt to remove non-JNI local reference, dumping thread
07-15 17:16:28.587 17779-17779/com.michaelsvit.kolnoa W/art: Attempt to remove non-JNI local reference, dumping thread
07-15 17:16:28.620 17779-17841/com.michaelsvit.kolnoa D/OpenGLRenderer: Use EGL_SWAP_BEHAVIOR_PRESERVED: true
07-15 17:16:28.639 17779-17829/com.michaelsvit.kolnoa W/chromium: [WARNING:data_reduction_proxy_config.cc(423)] SPDY proxy OFF at startup
07-15 17:16:28.740 17779-17841/com.michaelsvit.kolnoa I/OpenGLRenderer: Initialized EGL, version 1.4

                                                                        [ 07-15 17:16:28.741 17779:17841 D/         ]
                                                                        HostConnection::get() New Host Connection established 0xa0a5f8d0, tid 17841
07-15 17:16:28.782 17779-17841/com.michaelsvit.kolnoa W/EGL_emulation: eglSurfaceAttrib not implemented
07-15 17:16:28.782 17779-17841/com.michaelsvit.kolnoa W/OpenGLRenderer: Failed to set EGL_SWAP_BEHAVIOR on surface 0xaa3d9180, error=EGL_SUCCESS

                                                                        [ 07-15 17:16:28.815 17779:17850 D/         ]
                                                                        HostConnection::get() New Host Connection established 0xa0c82c80, tid 17850
07-15 17:16:29.166 17779-17779/com.michaelsvit.kolnoa W/BindingManager: Cannot call determinedVisibility() - never saw a connection for the pid: 17779
07-15 17:16:29.279 17779-17779/com.michaelsvit.kolnoa D/MovieGridFragment: 
07-15 17:16:29.768 17779-17779/com.michaelsvit.kolnoa W/BindingManager: Cannot call determinedVisibility() - never saw a connection for the pid: 17779
07-15 17:16:30.894 17779-17779/com.michaelsvit.kolnoa I/chromium: [INFO:CONSOLE(2)] "Uncaught TypeError: Cannot read property 'length' of undefined", source:  (2)
07-15 17:16:31.196 17779-17829/com.michaelsvit.kolnoa W/chromium: [WARNING:spdy_session.cc(2527)] Received WINDOW_UPDATE for invalid stream 1

最佳答案

按照我提出的想法,我保留了 XML 定义的 WebView(可见性设置为“消失”)并使用它,而不是在运行时创建它。从那以后我再也没有遇到过任何问题。

关于java - ART 在加载完成之前杀死 WebView,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38402165/

相关文章:

java - Spring webflux : how to use custom jackson ObjectWriter in ResponseEntityResultHandler?

android - 查找多个点之间的距离

c# - 如何在unity3d中加载一个html网页

javascript - Android webview位置检测javascript

java - 包含两个变量的列表

java - ANTLR标签异构替代品?

javascript - 如何重定向到 instagram ://user? username={username}

javascript - 将javascript函数加载到Android Kitkat中的webview

java - 在 Javascript 和 MongoDB 中使用 UTC 日期

java - 如果我不在扩展类中调用可选的 super 方法或构造函数会怎样?