webview的使用和注意事项
- 1 webview 使用
- 2.注意事项
-
- 1. 为什么Webview打开一个页面,播放一段音乐,退出Activity时音乐还在后台播放?
- 2.怎么用网页的标题来设置自己的标题栏?
- 3. 为什么打包之后JS调用失败(或者WebView与JavaScript相互调用时,如果是debug没有配置混淆时,调用时没问题的,但是当设置混淆后发现无法正常调用了)?
- 4. 5.0 以后的WebView加载的链接为Https开头,但是链接里面的内容,比如图片为Http链接,这时候,图片就会加载不出来,怎么解决?
- 5. WebView调用手机系统相册来上传图片,开发过程中发现在很多机器上无法正常唤起系统相册来选择图片。怎么解决?
- 6. WebView调用手机系统相册来上传图片,处理好第六点说的方法,我们打好release包测试的时候却又发现还是没法选择图片了,怎么解决?
- 7.怎么在 WebView 中长按保存图片?
- 8. WebView 开启硬件加速导致的问题?
- 9. ViewPager里非首屏WebView点击事件不响应是什么原因?
- 10.安卓8.0关于WebView的新特性
- 11.关于WebView的一点小优化
- 3.Android与JavaScript交互
1 webview 使用
https://www.jianshu.com/p/3e0136c9e748
1.加载页面
加载页面一般有以下几种形式:
//方式一:加载一个网页
webView.loadUrl("http://www.baidu.com");
//方式二:加载应用资源文件内的网页
webView.loadUrl("file:///android_asset/test.html");
//方式三:加载一段代码
webView.loadData(String data,String mimeType, String encoding);
其中,方式一和方式二比较好理解,方式三可能有些朋友不明白,我在这里解释一下。
WebView.loadData()和WebView.loadDataWithBaseURL()是表示加载某一段代码,其中, WebView.loadDataWithBaseURL()兼容性更好,适用场景更多,因此,我着重介绍一下这个方法。
WebView.loadDataWithBaseURL(String baseUrl, String data, String mimeType, String encoding, String historyUrl))
的五个参数:
baseUrl表示基础的网页,
data表示要加载的内容,
mimeType表示加载网页的类型,
encoding表示编码格式,
historyUrl表示可用历史记录,可以为null值。
举个例子:
String body = “示例:这里有个img标签,地址是相对路径”;
webView.loadDataWithBaseURL(“http://www.jcodecraeer.com”, body, “text/html”, “utf-8”,null);
加载后的网页:
loadDataWithBaseURL
加载有Header的网页:
HashMap<String,String> header = new HashMap<>();
...
webView.loadUrl(url,header);
注意:
如果你们直接用上面介绍的这三种方式来加载网页,很有可能会弹出系统浏览器进行网页访问,这样使用体验就会很差!
解决办法是在loadUrl() 之前加上这样一句代码:
webView.setWebViewClient(new WebViewClient());
这样就可以了,有的朋友可能会这样做,重写WebViewClient的shouldOverrideUrlLoading()方法:
webView.setWebViewClient(new WebViewClient(){
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
webView.loadUrl(url);
return true;
}
});
这个也是可以的,但是会有一些问题,这个会在后面介绍。
2.WebView的生命周期
WebView的生命周期一般跟随Activity:
@Override
protected void onResume() {
super.onResume();
//恢复webview的状态(不靠谱)
webView.resumeTimers();
//激活webView的状态,能正常加载网页
webView.onResume();
}
@Override
protected void onPause() {
super.onPause();
//当页面被失去焦点被切换到后台不可见状态,需要执行onPause
//通过onPause动作通知内核暂停所有的动作,比如DOM的解析、plugin的执行、JavaScript执行。
webView.onPause();
//当应用程序(存在webview)被切换到后台时,这个方法不仅仅针对当前的webview而是全局的全应用程序的webview
//它会暂停所有webview的layout,parsing,javascripttimer。降低CPU功耗。(不靠谱)
webView.pauseTimers();
}
//在关闭了Activity时,如果Webview的音乐或视频,还在播放。就必须销毁Webview
//但是注意:webview调用destory时,webview仍绑定在Activity上
//这是由于自定义webview构建时传入了该Activity的context对象
//因此需要先从父容器中移除webview,然后再销毁webview:
ViewGroup parent = findViewById(R.id.container);
parent.removeView(webView);
webView.destroy();
3、WebView的一些常用方法
浏览器是否可以前进/后退
//WebView是否可以后退
boolean canGoBack = webView.canGoBack();
//WebView后退
webView.goBack();
//WebView是否可以前进
boolean canGoForward = webView.canGoForward();
//WebView前进
webView.goForward();
//以当前的index为起始点前进或者后退到历史记录中指定的steps
//如果steps为负数则为后退,正数则为前进
boolean canGoBackOrForward = webView.canGoBackOrForward(step);
注意,点击系统返回键时,是结束当前的Activity,而非调用WebView的goBack()方法。
重新加载网页和停止加载
webView.reload(); //刷新页面(当前页面的所有资源都会重新加载)
webView.stopLoading(); //停止加载
清除浏览器缓存
//清除网页访问留下的缓存
//由于内核缓存是全局的因此这个方法不仅仅针对webview而是针对整个应用程序.
Webview.clearCache(true);
//清除当前webview访问的历史记录
//只会webview访问历史记录里的所有记录除了当前访问记录
Webview.clearHistory();
//这个api仅仅清除自动完成填充的表单数据,并不会清除WebView存储到本地的数据
Webview.clearFormData();
获取WebView高度、内容HTML高度和滚动距离
//获取当前可见区域的顶端距整个页面顶端的距离,也就是当前内容滚动的距离。
webView.getScrollY();
//获取WebView控件的高度。
webView.getHeight();webView.getBottom();
//获取HTML的高度(原始高度,不包括缩放后的高度)
webView.getContentHeight();
WebView下载文件
/**
* 当下载文件时打开系统自带的浏览器进行下载,当然也可以对捕获到的 url 进行处理在应用内下载。
**/
webView.setDownloadListener(new DownloadListener() {
@Override
public void onDownloadStart(String url, String userAgent, String contentDisposition, String mimetype, long contentLength) {
Uri uri = Uri.parse(url);
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);
}
});
4、WebView的常用工具类
4.1 WebSettings:对WebView进行配置和管理。
WebSettings webSettings = webView.getSettings();
//如果访问的页面中要与Javascript交互,则webview必须设置支持Javascript
webSettings.setJavaScriptEnabled(true);
//设置自适应屏幕,两者合用
webSettings.setUseWideViewPort(true); //将图片调整到适合webview的大小
webSettings.setLoadWithOverviewMode(true); // 缩放至屏幕的大小
webSettings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.SINGLE_COLUMN); //支持内容重新布局
//缩放操作
webSettings.setSupportZoom(true); //支持缩放,默认为true。是下面那个的前提。
webSettings.setBuiltInZoomControls(true); //设置内置的缩放控件。若为false,则该WebView不可缩放
webSettings.setDisplayZoomControls(false); //隐藏原生的缩放控件
webSettings.setTextZoom(2);//设置文本的缩放倍数,默认为 100
webSettings.setRenderPriority(WebSettings.RenderPriority.HIGH); //提高渲染的优先级
webSettings.setStandardFontFamily("");//设置 WebView 的字体,默认字体为 "sans-serif"
webSettings.setDefaultFontSize(20);//设置 WebView 字体的大小,默认大小为 16
webSettings.setMinimumFontSize(12);//设置 WebView 支持的最小字体大小,默认为 8
// 5.1以上默认禁止了https和http混用,以下方式是开启
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
webSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
}
//其他操作
webSettings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK); //关闭webview中缓存
webSettings.setAllowFileAccess(true); //设置可以访问文件
webSettings.setJavaScriptCanOpenWindowsAutomatically(true); //支持通过JS打开新窗口
webSettings.setLoadsImagesAutomatically(true); //支持自动加载图片
webSettings.setDefaultTextEncodingName("utf-8");//设置编码格式
webSettings.setGeolocationEnabled(true);//允许网页执行定位操作
webSettings.setUserAgentString("Mozilla/5.0 (Windows NT 10.0; WOW64; rv:50.0) Gecko/20100101 Firefox/50.0");//设置User-Agent
//不允许访问本地文件(不影响assets和resources资源的加载)
webSettings.setAllowFileAccess(false);
webSettings.setAllowFileAccessFromFileURLs(false);
webSettings.setAllowUniversalAccessFromFileURLs(false);
其中,WebView设置缓存,当加载 html 页面时,WebView会在/data/data/package/下生成 database 与 cache 两个文件夹
请求的URL记录保存在WebViewCache.db,而URL的内容是保存在WebViewCache文件夹下:
//缓存模式如下:
//LOAD_CACHE_ONLY: 不使用网络,只读取本地缓存数据
//LOAD_DEFAULT: (默认)根据cache-control决定是否从网络上取数据。
//LOAD_NO_CACHE: 不使用缓存,只从网络获取数据.
//LOAD_CACHE_ELSE_NETWORK,只要本地有,无论是否过期,或者no-cache,都使用缓存中的数据。
//优先使用缓存:
webSettings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
//不使用缓存:
webSettings.setCacheMode(WebSettings.LOAD_NO_CACHE)
还有如下几种:
//开启 DOM storage API 功能 较大存储空间,使用简单
settings.setDomStorageEnabled(true);
//设置数据库缓存路径 存储管理复杂数据 方便对数据进行增加、删除、修改、查询 不推荐使用
settings.setDatabaseEnabled(true);
final String dbPath = context.getApplicationContext().getDir("db", Context.MODE_PRIVATE).getPath();
settings.setDatabasePath(dbPath);
//开启 Application Caches 功能 方便构建离线APP 不推荐使用
settings.setAppCacheEnabled(true);
final String cachePath = context.getApplicationContext().getDir("cache", Context.MODE_PRIVATE).getPath();
settings.setAppCachePath(cachePath);
settings.setAppCacheMaxSize(5 * 1024 * 1024);
WebView缓存
4.2 WebViewClient:处理各种通知和请求事件。
WebViewClient类常用方法:
shouldOverrideUrlLoading():拦截URL请求,重定向(有2个方法,一个是兼容5.0以下,一个是兼容5.0以上,保险起见两个都重写)。
无论返回true还是false,只要为WebView设置了WebViewClient,系统就不会再将url交给第三方的浏览器去处理了。q其中返回false,代表将url交给当前WebView加载,也就是正常的加载状态;shouldOverrideUrlLoading()返回true,代表开发者已经对url进行了处理,WebView就不会再对这个url进行加载了。
另外,使用post的方式加载页面,此方法不会被调用。
webView.setWebViewClient(new WebViewClient(){
//重定向URL请求,返回true表示拦截此url,返回false表示不拦截此url。
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
//作用1:重定向url
if(url.startsWith("weixin://")){
url = url.replace("weixin://","http://");
webView.loadUrl(url);
}
//作用2:在本页面的WebView打开,防止外部浏览器打开此链接
view.loadUrl(url);
return true;
}
});
onPageStarted()onPageFinished():页面加载时和页面加载完毕时调用。
shouldOverrideKeyEvent():重写此方法才能处理浏览器中的按键事件。
shouldInterceptRequest():页面每一次请求资源之前都会调用这个方法(非UI线程调用)。
onLoadResource():页面加载资源时调用,每加载一个资源(比如图片)就调用一次。
onReceivedError():加载页面的服务器出现错误(比如404)时回调。
onReceivedSslError():重写此方法可以让webview处理https请求。
doUpdateVisitedHistory():更新历史记录。
onFormResubmission():应用程序重新请求网页数据。
onReceivedHttpAuthRequest():获取返回信息授权请求。
onScaleChanged():WebView发生缩放改变时调用。
onUnhandledKeyEvent():Key事件未被加载时调用。
补充,关键方法调用流程:
情况一:loadUrl()无重定向时
onPageStarted->onPageFinished
情况二:loadUrl()网页A重定向到B时
onPageStarted->shouldOverrideUrlLoading->onPageStarted->onPageFinished->onPageFinished
情况三:在已加载的页面中点击链接,加载页面A(无重定向)
shouldOverrideUrlLoading->onPageStarted->onPageFinished
情况四:在已加载的页面中点击链接,加载页面A(页面A重定向至页面B)
shouldOverrideUrlLoading->onPageStarted->shouldOv