在触及Android 4.2.2之前,WebView无法呈现

时间:2013-02-28 04:51:45

标签: android android-webview

我正在开发一个名为Lightning Browser的开源浏览器,我在Android(4.2.2)的最新更新时遇到了一些麻烦。

在触摸视图之前,WebViews将无法完全呈现。它只发生在最新的Android版本上。在4.2.1上,WebView呈现完全正常。我使用Nexus 7进行开发,在收到4.2.2更新后,浏览器停止渲染。其他用户也经历过这种情况,并且仅在4.2.2上多次确认。它正在针对API级别16和17进行,但我看到了一个针对API级别9的WebKit浏览器,没有出现此问题。

我试图使用我在Stack Overflow(Android WebView renders blank/white, view doesn't update on css changes or HTML changes, animations are choppy)上找到的问题的解决方案来解决这个问题。但是,单独将WebView的RenderPriority设置为high并不能解决它...在不触及的情况下使其呈现的唯一方法是将invalidate()命令放在WebView的OnDraw()方法中。这会导致WebView不断重绘。这样(有点),动画是平滑的,页面加载非常快,但它会导致WebView的性能下降。

我也看过这个问题(与我的非常相似),但没有好的答案。 Android WebView Fails to Completely Render Content Until User Interaction

通过性能下降,我的意思是输入。文本输入滞后,WebView本身无法处理以前发生的事情。使用invalidate()方法调用对浏览器进行基准测试会使基准测试性能下降约8%。我知道基准测试不是一切,但它告诉我连续绘图使系统紧张并导致系统忽略其他任务。

结论...... Android 4.2.2中的WebView在触摸之前不会呈现。我知道解决这个问题的唯一方法是在WebView的onDraw()方法中调用invalidate()。这对性能有害,我正在寻找一种不同的解决方法。

魔法代码(我目前正在使用)......

class MyWebView extends WebView
{
    @Override
    onDraw(Canvas canvas)
    {
        invalidate(); 
        super.OnDraw(canvas);
    }
}

除去

invalidate();

并且在触摸之前不会渲染。

有没有人建议如何使WebView渲染(除了我做过的)?顺便说一句,这是我在Stack上问过的第一个问题,如果我不清楚或者我做错了什么,请原谅我。

编辑: 我发现这个问题here关于一个类似的问题已经解决,问题是,我不明白答案甚至意味着什么。如果有人能够启发我可能会有所帮助。

我在logcat

中遇到此错误
E/chromium(1243): external/chromium/net/disk_cache/backend_impl.cc:2022: [0705/172030:ERROR:backend_impl.cc(2022)] Corrupt Index file

4 个答案:

答案 0 :(得分:9)

所以我终于找到了导致WebView无法渲染的问题。我正在WebView的WebViewClient中启动并停止drawable的动画。这个drawable只是一个刷新按钮,在页面加载时旋转......简单吧?

在浏览器的非全屏模式下,旋转drawable和WebView都是同一父项的子项,而在全屏模式下,drawable成为WebView的子项。不知何故,通过在页面加载时启动动画并在完成时停止它(在全屏幕中),应用程序决定旋转drawable是需要所有绘图能力而WebView从不绘制的。当处于全屏模式并且drawable成为WebView的子级时,WebView的渲染优先级高于drawable,并且绘制得很好。

故事的寓意是...... WebViews喜欢成为最优先考虑的视图。如果有其他视图获得更高的优先级,则它们将无法正确绘制。

我不是动画方面的专家,所以我需要重新思考我现在如何设置drawable动画,以免打断WebView。

希望这是有道理的。谢谢你的阅读。

答案 1 :(得分:4)

禁用清单上的硬件加速:

机器人:硬件加速= “假”

答案 2 :(得分:2)

请查看@Olivier在Android WebView renders blank/white, view doesn't update on css changes or HTML changes, animations are choppy上的最后一个答案,他在WebView的OnTouchEvent上触发了几个延迟的无效,而不是继续在onDraw上...在我的情况下它起作用,因为(大多数)我的问题是在用户触摸webview,我更改了一些CSS作为回应。当然它根本不适用于自动/超时的css

的情况

在我的情况下,它还有助于从Java导出JavaScript函数以手动触发带有延迟的无效,因此如果在JavaScript中您或多或少知道灾难可能发生的位置,您可以手动触发它,类似于内部类内部你的WebView:

public class MyWebView extends WebView {

    private class InvalidateExtension {

        private Handler handler=new Handler(); // you might already have a handler
        private Runnable mInvalidater=new Runnable() {

            @Override
            public void run() {
                MyWebView.this.invalidate();
            }

        }

        public void trigger(int delay) {
                handler.postDelayed(mInvalidater, delay);
                handler.postDelayed(mInvalidater, 2*delay); // just in case
                handler.postDelayed(mInvalidater, 4*delay); // just in case just in case :)
        }
    }


    /** Call this function on this view's init, BEFORE loading a page so it is available to JS */
    private void call_me_on_init_to_enable_hack() {
        addJavascriptInterface(new InvalidateExtension(), "Invalidater");
    }
}

因此,您可以从JavaScript中执行以下操作:

Invalidater.trigger(100);

玩毫秒值......

希望这有助于某人!

答案 3 :(得分:2)

旋转手机时缩放比例存在问题,这将导致此问题,不会绘制部分或整个页面。要在WebViewClient实现中解决此覆盖onScaleChanged并使视图无效。这应该会在需要时强制重绘。

@Override
    public void onScaleChanged(WebView view, float oldScale, float newScale) {
        if (view != null) {
            view.invalidate();
        }
    }