Android layer type與WebView白屏-第一次加載webview很慢


在項目中遇到WebView在加載圖片的時候會出現白屏的情況,后來在xml設置了WebView屬性,問題的到解決:

 @SuppressWarnings("deprecation")  
    @Override  
    protected void onDestroy() {  
     if (mWebView != null){  
         try { 
//           mWebView.clearView();  
//           mWebView.loadUrl("about:blank");  
             mWebView.clearCache(true);  
             mWebView.destroy();// 窗體銷毀,要webview銷毀;考慮安全問題和內存溢出  
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
     }  
        MyLog.e(TGA, "  窗體銷毀");  
        isDestroy=true;  
        System.gc();  
        super.onDestroy();  
    }  

 

 <WebView   android:id="@+id/webview"  
           android:layout_width="fill_parent"  
            android:layout_height="fill_parent"  
          android:layerType="software"   
          android:scrollbars="none" />  

 

在網上也有layer的一些資料:

以下摘自http://blog.csdn.net/a345017062/article/details/7478667

 

先說說這三個layer。

LAYER_TYPE_SOFTWARE 無論硬件加速是否打開,都會有一張Bitmap(software layer),並在上面對WebView進行軟渲染。 好處: 在進行動畫,使用software可以只畫一次View樹,很省。 什么時候不要用: View樹經常更新時不要用。尤其是在硬件加速打開時,每次更新消耗的時間更多。因為渲染完這張Bitmap后還需要再把這張Bitmap渲染到hardware layer上面去。

LAYER_TYPE_HARDWARE 硬件加速關閉時,作用同software。 硬件加速打開時會在FBO(Framebuffer Object)上面做渲染,在進行動畫時,View樹也只需要畫一次。

兩者區別: 1、一個是渲染到Bitmap,一個是渲染到FB上。 2、hardware可能會有一些操作不支持。 兩者相同: 都是開了一個buffer,把View畫到這個buffer上面去。

LAYER_TYPE_NONE 這個就比較簡單了,不為這個View樹建立單獨的layer

PS:GLSurfaceView和WebView默認Layertype都是none。

GLSurfaceView: 給GLSurfaceView設置為software或者hardware后,發現什么也畫不出來了。得出結論:GLSurfaceView的Layer type只能是none

WebView: 以前使用WebView時碰到過一個問題,如果在WebView上面使用Animation,WebView的繪畫區域不動。當時的解決方案是在進行動畫之前對WebView進行截屏(drawingcache)。按上面的道理試了一下,設置一個hardware或者software的layer就OK了。

現在又碰到了另外一個問題,打開硬件加速后,在一些機器上面(我的是3.2)WebView有時會出現某一塊區域白屏的問題。默認的layer type是none,改為hardware也不行,設置為software就解決了。當然關閉硬件加速也好了,可是那樣的話程序整體就比較慢了。所以最終方案是整體硬件加速,出問題的WebView設置software

 

補充於2012.4.21:

加上這一句,可以讓3D的繪制更快一些:getHolder().setType(SurfaceHolder.SURFACE_TYPE_HARDWARE);

 

 

補充於2012.4.22

先說問題:  在硬件加速開啟的情況下GLSurfaceView一旦被從View樹上摘下來,會使整個窗口背景變黑,即使設置layer type為software也不管用。  經過兩天的排查,發現了原因,我的程序是在C層由drawFrame(屬於GLThread線程)來驅動進行繪畫,當GLSurfaceView被摘下來時,GLSurfaceView的destroy方法被調用,我在destroy方法(屬於UI線程)中直接調用 了GLThread線程的結束方法。而GLSurfaceView.creat,sizeChanged,destroyed在UI線程,Render.create,sizeChanged,drawFrame在GLThread線程。因此,出現了UI線程直接調用GLThread線程的方法的問題。最終通過GLSurfaceView.queueEvent向GLThread線程發送Runnable,問題得到解決。  看來,還是軟渲染的容錯能力比較強,一開硬件加速,底層就比較脆弱了。  結論:一定要搞清楚哪個是UI線程,哪個是GLThread線程。

 補上幾個尋找問題過程中發現的知識點: hardware acclerator是對整個窗口進行加速,在硬件加速打開時View.isHardwareAcclerator返回true。但每個View可能被渲染到的Canvas是不同的,比如View可能被通過setLayer設置了Layer,這時,Canvas.isHardwareAccelerator返回false Android提供了三種硬件加速是否打開的控制級別,分別是Application,Activity,Window,View。這個可以參考Dev Guide


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM