WebView在Android 4.2.2之前无法渲染
我正在开发一款名为Lightning browser的开源浏览器,在Android的最新更新(4.2.2)中遇到了一些问题 在触摸视图之前,WebView将无法完全渲染。它只出现在最新的Android版本上。在4.2.1中,WebView呈现得非常好。我使用Nexus7进行开发,在收到4.2.2更新后,浏览器立即停止渲染。其他用户也经历过这种情况,并多次确认仅在4.2.2上发生。它的目标是API级别16和17,但我已经看到一个WebKit浏览器,它的目标是API级别9,而没有这个问题 我尝试使用我在这里发现的堆栈溢出()问题的解决方案来解决这个问题。但是,仅将WebView的RenderPriority设置为high并不能解决此问题。。。要使其在不被触摸的情况下进行渲染,唯一的方法是将invalidate()命令放在WebView的OnDraw()方法中。这会导致WebView连续重新绘制。这可以工作(某种程度上),动画是平滑的,页面加载非常快,但它会导致WebView的性能下降 我也看到过这个问题(与我的问题非常相似),但没有很好的答案 所谓性能下降,我指的是输入。文本输入滞后,WebView本身无法像以前那样处理正在发生的事情。使用invalidate()方法调用对浏览器进行基准测试会降低大约8%的基准测试性能。我知道基准并不是一切,但它告诉我连续绘图会使系统紧张,并导致系统忽略其他任务 总之。。。 Android 4.2.2中的WebView在触摸之前不会渲染。我知道解决这个问题的唯一方法是在WebView的onDraw()方法中调用invalidate()。这对性能不好,我正在寻找一种不同的方法来解决这个问题 魔法代码(我目前正在使用) 除去WebView在Android 4.2.2之前无法渲染,android,android-webview,Android,Android Webview,我正在开发一款名为Lightning browser的开源浏览器,在Android的最新更新(4.2.2)中遇到了一些问题 在触摸视图之前,WebView将无法完全渲染。它只出现在最新的Android版本上。在4.2.1中,WebView呈现得非常好。我使用Nexus7进行开发,在收到4.2.2更新后,浏览器立即停止渲染。其他用户也经历过这种情况,并多次确认仅在4.2.2上发生。它的目标是API级别16和17,但我已经看到一个WebKit浏览器,它的目标是API级别9,而没有这个问题 我尝试使用
invalidate();
它在被触摸之前不会渲染
除了我所做的以外,有人对如何进行WebView渲染有什么建议吗?顺便说一下,这是我在Stack上问的第一个问题,如果我不清楚或者我做错了什么,请原谅我
编辑:
我发现这个问题是关于一个类似的问题,它被解决了,问题是,我甚至不明白答案的意思。如果有人能启发我,那可能会有帮助
我在logcat中得到这个错误
E/chromium(1243): external/chromium/net/disk_cache/backend_impl.cc:2022: [0705/172030:ERROR:backend_impl.cc(2022)] Corrupt Index file
因此,我最终发现了导致WebView无法渲染的问题。我正在启动和停止WebView的WebViewClient中可绘制的动画。这个可绘制的只是一个刷新按钮,当页面加载时它会旋转。。。简单对吧 在浏览器的非全屏模式下,旋转可绘制和WebView都是同一父对象的子对象,而在全屏模式下,可绘制成为WebView的子对象。不知何故,通过在页面加载时启动动画并在加载完成时停止动画(全屏),应用程序决定旋转可绘制文件需要所有绘图功能,而WebView永远不会绘制。当处于全屏模式且可绘制文件成为WebView的子文件时,WebView的渲染优先级高于可绘制文件,并且绘制效果良好 这个故事的寓意是。。。WebView喜欢成为要绘制的优先级最高的视图。如果有其他视图具有更高的优先级,它们将无法正确绘制 我不是动画方面的专家,所以我需要重新思考我现在是如何制作可绘制动画的,这样就不会中断网络视图
希望这是有道理的。感谢阅读。请看@Olivier on的最后一个答案,他在WebView的OnTouchEvent上触发了几次延迟失效,而不是在onDraw上继续。。。在我的例子中,它起作用了,因为(大多数)我的问题是在用户触摸webview之后,我改变了一些CSS作为回应。当然,它根本不适用于自动/超时css 在我的例子中,它还帮助从Java导出JavaScript函数以延迟手动触发invalidate,因此,如果在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);
并播放毫秒值
希望这对别人有帮助 禁用清单上的硬件加速:
android:hardwareAccelerated=“false”旋转手机时缩放比例出现问题,这将导致此问题,部分或整个页面将无法绘制。要解决此覆盖问题,请在WebViewClient实现中更改并使视图无效。这将在需要时强制重新绘制
@Override
public void onScaleChanged(WebView view, float oldScale, float newScale) {
if (view != null) {
view.invalidate();
}
}
说到动画,我已经看到,如果你在页面的某个地方应用一个虚拟HTML动画,它将触发webview重画。。。但这是一个非常肮脏的黑客…天哪。那正是我在做的!我被困了好几天,为什么抽绳不能加载。谢谢。所以答案是不使用旋转动画?但这不会发生在运行Android Kitkat的设备上。他们解决了什么问题吗?这个问题与我们的问题无关,页面是空白的,但是因为加载它时出现了一些奇怪的问题,与渲染管道无关。顺便说一句。。。同样在我的例子中,键盘/输入性能非常糟糕(并且随着页面复杂性的增加而降低),因此我选择在运行时使用JQuery,在选择HTML输入时触发本机输入覆盖。它不是很优雅,但本机输入工作完美无瑕,文本选择/剪切/粘贴并不令人沮丧……一个不会降低性能的替代方案:)可能不是最好的解决方案,但对我的案例唯一有效。这是可行的,但正如@Scarmysun所说的,不适合我,但我建议关闭硬件acc
@Override
public void onScaleChanged(WebView view, float oldScale, float newScale) {
if (view != null) {
view.invalidate();
}
}