本文介绍了使用一段时间后,我的应用程序在滚动 WebView 期间冻结,说“无法锁定表面"的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的 Android 应用程序由多个活动组成,每个活动负责一个片段(目前).我的片段通常显示/附加有点像这样:

My Android app consists of several activities, each responsible for a single fragment (for now). My fragments are usually displayed/attached somewhat like this:

mTopicFragment = (TopicFragment)getSupportFragmentManager().findFragmentByTag("topic");
if(mTopicFragment == null)
    mTopicFragment = TopicFragment.newInstance(bid, page, pid);

if (savedInstanceState == null) {
    getSupportFragmentManager().beginTransaction()
            .add(R.id.content, mTopicFragment, "topic")
            .commit();
}

TopicFragment 包含一个显示一些 HTML 和 CSS/JS 内容的 WebView.在浏览应用程序一段时间后,这些 TopicFragment WebViews 之一的滚动变得缓慢,最终,应用程序完全冻结.ADB 日志显示以下异常:

The TopicFragment contains a WebView displaying some HTML and CSS/JS stuff. After some time of browsing through the app, the scrolling in one of these TopicFragment WebViews becomes slow and eventually, the App freezes completely. The ADB log shows the following exception:

12-12 22:49:33.931  12582-12582/com.mde.potdroid3 W/Adreno-EGLSUB﹕ <DequeueBuffer:606>: dequeue native buffer fail: Unknown error 2147483646, buffer=0x0, handle=0x0
12-12 22:49:33.941  12582-12582/com.mde.potdroid3 W/Adreno-EGLSUB﹕ <DequeueBuffer:606>: dequeue native buffer fail: Invalid argument, buffer=0x0, handle=0x0
12-12 22:49:33.941  12582-12582/com.mde.potdroid3 W/Adreno-ES20﹕ <gl2_surface_swap:43>: GL_OUT_OF_MEMORY
12-12 22:49:33.941  12582-12582/com.mde.potdroid3 W/Adreno-EGL﹕ <qeglDrvAPI_eglSwapBuffers:3597>: EGL_BAD_SURFACE
12-12 22:49:33.941  12582-12582/com.mde.potdroid3 W/HardwareRenderer﹕ EGL error: EGL_BAD_SURFACE
12-12 22:49:33.951  12582-12582/com.mde.potdroid3 W/HardwareRenderer﹕ Mountain View, we've had a problem here. Switching back to software rendering.

12-12 22:20:04.461  10081-10081/com.mde.potdroid3 E/Surface﹕ dequeueBuffer failed (Unknown error 2147483646)
12-12 22:20:04.461  10081-10081/com.mde.potdroid3 E/ViewRootImpl﹕ Could not lock surface
    java.lang.IllegalArgumentException
            at android.view.Surface.nativeLockCanvas(Native Method)
            at android.view.Surface.lockCanvas(Surface.java:243)
            at android.view.ViewRootImpl.drawSoftware(ViewRootImpl.java:2435)
            at android.view.ViewRootImpl.draw(ViewRootImpl.java:2409)
            at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:2253)
            at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1883)
            at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1000)
            at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5670)
            at android.view.Choreographer$CallbackRecord.run(Choreographer.java:761)
            at android.view.Choreographer.doCallbacks(Choreographer.java:574)
            at android.view.Choreographer.doFrame(Choreographer.java:544)
            at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:747)
            at android.os.Handler.handleCallback(Handler.java:733)
            at android.os.Handler.dispatchMessage(Handler.java:95)
            at android.os.Looper.loop(Looper.java:136)
            at android.app.ActivityThread.main(ActivityThread.java:5081)
            at java.lang.reflect.Method.invoke(Native Method)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:781)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)

在互联网上,我只能找到有关此异常的信息,其中人们有他们的自定义视图.这里会发生什么?它可能与我的应用程序的内存消耗有关吗?似乎每次我调用上面的代码时,都会实例化、显示一个新的 TopicFragment 并推送到后堆栈.我怎样才能进一步调试这种行为?

On the internet, I can only find information regarding this Exception, where People have their custom Views. What happens here? Can it be related to memory consumption of my app? It appears as if each time I call the code above, a new TopicFragment is instantiated, displayed and pushed to the back stack. How could I further debug this behaviour?

另外一个信息:当我在开发人员设置中启用覆盖时,该应用程序似乎使用了大量 CPU.可能是我的片段在我离开它们时没有正确分离并且出于某种原因继续在后台运行?

One more info: The App seems to use a LOT of CPU when I enable the overlay in the developer settings. May it be, that my fragments are not properly detached when I leave them and for some reason keep running in the background?

这就是我使用 WebView 的方式:

This is how I use the WebView:

mWebView = (WebView)getView().findViewById(R.id.topic_webview);
mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.getSettings().setDomStorageEnabled(true);
mWebView.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE);
mWebView.getSettings().setAllowFileAccess(true);
mWebView.addJavascriptInterface(mJsInterface, "api");
mWebView.setWebChromeClient(new WebChromeClient());
mWebView.loadData("", "text/html", "utf-8");
mWebView.setBackgroundColor(0x00000000);

不是这里提到的内存泄漏.

推荐答案

我终于找到了问题所在.关闭 WebView 的硬件加速可以解决这个问题.

I finally found the issue. Switching off hardware acceleration for the WebView solves it.

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle saved) {
    //...
    if (Utils.isKitkat()) {
        disableHardwareAcc();
    }
    //...
}

@TargetApi(Build.VERSION_CODES.HONEYCOMB)
protected void disableHardwareAcc() {
    mWebView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
}

这篇关于使用一段时间后,我的应用程序在滚动 WebView 期间冻结,说“无法锁定表面"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-26 08:19