关键属性:
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);
}
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>";
}
通过这个方式我们可以有效的增大我们的APP运行内存,并减少由于Webview导致的OOM.,在androidmanifest.xml的activity标签里加上Android:process=”packagename.web”就可以了,代码如下:
<activity
android:name=".WebViewActivity"
android:process="com.web"
android:label="@string/app_name" >
activity>
4.0以上的系统我们开启硬件加速后,WebView渲染页面更加快速,拖动也更加顺滑。但有个副作用就是,当WebView视图被整体遮住一块,然后突然恢复时(比如使用SlideMenu将WebView从侧边滑出来时),这个过渡期会出现白块同时界面闪烁。解决这个问题的方法是在过渡期前将WebView的硬件加速临时关闭,过渡期后再开启,代码如下:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
webview.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
}
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 后直接销毁这个进程,即使内存泄露了,也不会影响到主进程。微信,手 Q 等 App 也采用了这个方案。但是这就涉及到了跨进程通讯,处理起来就比较麻烦。
另外个解决方案,就是使用自己封装的 WebView,比如上面提到的 X5 内核,且使用 WebView 的时候,不在 XML 里面声明,而是在代码中直接 new 出来,传入 application context 来防止 activity 引用被滥用。
WebView webView = new WebView(getContext().getApplicationContext());
webFrameLayout.addView(webView, 0);
更详细的解决办法:点击这里跳转