Android关于webview自适应与优化

  • webview的适配和优化
      • webview自适应pc网页屏幕
      • 更改html样式设置
    • webview的优化
        • webview独立进程
        • webview硬件加速导致页面渲染的闪烁
        • Html5跳转原生界面
        • 使用第三方WebView内核
        • WebView的OOM的问题

webview的适配和优化


webview自适应pc网页屏幕

  • 关键属性:
    webSettings.setLayoutAlgorithm(LayoutAlgorithm.NARROW_COLUMNS);
    webSettings.setUseWideViewPort(true);


  • 全部代码

WebSettings webSettings = view.getSettings();  
webSettings.setJavaScriptEnabled(true);  
webSettings.setJavaScriptCanOpenWindowsAutomatically(true);  
webSettings.setUseWideViewPort(true); 
webSettings.setLayoutAlgorithm(LayoutAlgorithm.SINGLE_COLUMN);    
webSettings.setDisplayZoomControls(false);  
webSettings.setAllowFileAccess(true); 
webSettings.setBuiltInZoomControls(true);  
webSettings.setSupportZoom(true);  
webSettings.setLoadWithOverviewMode(true);    
/**webView.getSettings().setLayoutAlgorithm(LayoutAlgorithm.SINGLE_COLUMN);这个属性
可以让webview只显示一列,也就是自适应页面大小 不能左右滑动,但在使用中发现,只针对4.4以下有效,因为4.4的webview内核改了,Google也在api中说了,要么改html样式,要么改变WebView;
*/
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            tvRouterDesc.getSettings().setLayoutAlgorithm(LayoutAlgorithm.TEXT_AUTOSIZING);
        } else {
            tvRouterDesc.getSettings().setLayoutAlgorithm(LayoutAlgorithm.NORMAL);
        }
/**  
 * 用WebView显示图片,可使用这个参数 设置网页布局类型: 1、LayoutAlgorithm.NARROW_COLUMNS :  
 * 适应内容大小 2、LayoutAlgorithm.SINGLE_COLUMN:适应屏幕,内容将自动缩放  
 *   webSettings.setLayoutAlgorithm(LayoutAlgorithm.NARROW_COLUMNS);  
 */  


//下方代码已经过时(不再沿用)
DisplayMetrics metrics = new DisplayMetrics();  
  getWindowManager().getDefaultDisplay().getMetrics(metrics);  
  int mDensity = metrics.densityDpi;  
  if (mDensity == 240) {   
   webSettings.setDefaultZoom(ZoomDensity.FAR);  
  } else if (mDensity == 160) {  
     webSettings.setDefaultZoom(ZoomDensity.MEDIUM);  
  } else if(mDensity == 120) {  
   webSettings.setDefaultZoom(ZoomDensity.CLOSE);  
  }else if(mDensity == DisplayMetrics.DENSITY_XHIGH){  
   webSettings.setDefaultZoom(ZoomDensity.FAR);   
  }else if (mDensity == DisplayMetrics.DENSITY_TV){  
   webSettings.setDefaultZoom(ZoomDensity.FAR);   
  }else{  
      webSettings.setDefaultZoom(ZoomDensity.MEDIUM);  
  }  



更改html样式设置

    private String getHtmlData(String bodyHTML) {
        String head = "<head><style>img{max-width: 100%; width:auto; height: auto;}style>head>";
        return "<html>" + head + "<body>" + bodyHTML + "body>html>";
    }

webview的优化

webview独立进程

通过这个方式我们可以有效的增大我们的APP运行内存,并减少由于Webview导致的OOM.,在androidmanifest.xml的activity标签里加上Android:process=”packagename.web”就可以了,代码如下:

<activity  
    android:name=".WebViewActivity"  
    android:process="com.web"  
    android:label="@string/app_name" >  
activity>  

webview硬件加速导致页面渲染的闪烁

4.0以上的系统我们开启硬件加速后,WebView渲染页面更加快速,拖动也更加顺滑。但有个副作用就是,当WebView视图被整体遮住一块,然后突然恢复时(比如使用SlideMenu将WebView从侧边滑出来时),这个过渡期会出现白块同时界面闪烁。解决这个问题的方法是在过渡期前将WebView的硬件加速临时关闭,过渡期后再开启,代码如下:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
    webview.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
}

Html5跳转原生界面

跳转逻辑结构如下图:
Android关于webview自适应与优化_第1张图片
代码如下:

webview.setWebViewClient(new WebViewClient() {

  @Override
  public boolean shouldOverrideUrlLoading(WebView view, String url) {
   parserURL(url); //解析url,如果存在有跳转原生界面的url规则,则跳转原生。
   return super.shouldOverrideUrlLoading(view, url);
  }

  @Override
  public void onPageFinished(WebView view, String url) {
   super.onPageFinished(view, url);
  }

  @Override
  public void onLoadResource(WebView view, String url) {
   super.onLoadResource(view, url);
  }
 });

在执行上面的条件前,我们需要在清单文件中进行定义。声明一下 就可以在自带浏览器通过uri scheme跳到本app页面了,这个activity作为各个页面的分发页面,通过这个界面解析数据决定接下来要跳转哪个页面:

<activity
 android:name=".ui.webview.CommWebviewActivity"
 android:configChanges="orientation|keyboardHidden|screenSize"
 android:process=":webview"
 android:screenOrientation="portrait"
 android:windowSoftInputMode="stateHidden">
 <intent-filter>
  <category android:name="android.intent.category.BROWSABLE" />
  <category android:name="android.intent.category.DEFAULT" />

  <action android:name="android.intent.action.VIEW" />

  <data
   android:host="xxxx.com"
   android:scheme="kingp2p" />
 intent-filter>
activity>

使用第三方WebView内核

这里推荐腾讯浏览服务
感兴趣的朋友可以跳转到官网进行查看,确实挺强大的。

WebView的OOM的问题

这里提到的让 WebView 独立运行在一个进程里,用完 WebView 后直接销毁这个进程,即使内存泄露了,也不会影响到主进程。微信,手 Q 等 App 也采用了这个方案。但是这就涉及到了跨进程通讯,处理起来就比较麻烦。

另外个解决方案,就是使用自己封装的 WebView,比如上面提到的 X5 内核,且使用 WebView 的时候,不在 XML 里面声明,而是在代码中直接 new 出来,传入 application context 来防止 activity 引用被滥用。

WebView webView =  new WebView(getContext().getApplicationContext());
webFrameLayout.addView(webView, 0);

更详细的解决办法:点击这里跳转

你可能感兴趣的:(Android--自定义控件)