WebView 使用总结
WevView是Android平台上一种特殊的View,是基于webkit引擎的,展现web网页的一种控件。WebView的内部实现是采用渲染引擎展示View的内容,提供了网页的前进、后退、缩放和搜索等功能,在android4.4之后直接采用chrom当做引擎。
####加载html的四种方式
webView.loadUrl("http://139.196.35.30:8080/OkHttpTest/apppackage/test.html");//加载url
webView.loadUrl("file:///android_asset/test.html");//加载asset文件夹下html
//方式3:加载手机sdcard上的html页面
webView.loadUrl("content://com.ansen.webview/sdcard/test.html");
//方式4 使用webview显示html代码
webView.loadDataWithBaseURL(null,"<html><head><title> 欢迎您 </title></head>" +
"<body><h2>使用webview显示 html代码</h2></body></html>", "text/html" , "utf-8", null);
####WebSettings类
主要是一些设置相关的,例如设置缓存,缩放等,具体设置入下
/ 通过设置WebView的settings来实现
WebSettings settings = getSettings();
settings.setJavaScriptEnabled(true);
settings.setPluginState(WebSettings.PluginState.ON);
settings.setAllowContentAccess(true);
settings.setAllowFileAccess(true);
settings.setAllowFileAccessFromFileURLs(true);
settings.setSupportZoom(true);
//设置出现缩放工具
settings.setBuiltInZoomControls(true);
//设定缩放控件隐藏
settings.setDisplayZoomControls(false);
/**
* 简单来说,该项设置决定了JavaScript能否访问来自于任何源的文件标识的URL。
* 比如我们把PDF.js放在本地assets里,然后通过一个URL跳转访问来自于任何URL的PDF,所以这里我们需要将其设置为true。
* 而一般情况下,为了安全起见,是需要将其设置为false的。
*/
settings.setAllowUniversalAccessFromFileURLs(true);
// 1. 设置缓存路径 ------ application 缓存
String cacheDirPath = mContext.getFilesDir().getAbsolutePath() + "cache/";
settings.setAppCachePath(cacheDirPath);
// 2. 设置缓存大小
settings.setAppCacheMaxSize(PlayerConstants.WEBVIEW_CACHE_SIZE);
// 3. 开启Application Cache存储机制
settings.setAppCacheEnabled(true);
// 开启DOM storage
settings.setDomStorageEnabled(true);
// 只需设置支持JS就自动打开IndexedDB存储机制
settings.setJavaScriptEnabled(true);
//根据网络联网情况设置不同的缓存模式
settings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
####WebViewClient与WebChromeClient区别
在使用WebView的时候基本都会用到这个类,下面说一下他们的主要区别。
#####WebViewClient主要帮助WebView处理各种通知和请求事件,有一下常用方法:
-onPageFinished 页面请求完成。
-onPageState 页面开始加载。
-shouldOverrideUrlLoading 拦截url。
-onRecoveredError 访问错误时候的回调。
#####WebChromeClient主要是与js相关操作的方法。
-onJsAlert WebView不支持js的alert的弹框,需要自己监听然后处理。
-onReceivedTitle 获取网页标题。
-onReceivedIcon 获取网页的icon。
-onProgressChanged 加载进度回调。
####Android调用js
javascript:再加上js里面的方法,具体实例如下代码:
mVebView.loadUrl("javascript:renderPage("+mCount+","+38+")");
其中renderPage是js代码中的方法,下面贴出js代码如下:
var url = location.search.substring(1);
PDFJS.cMapUrl = 'https://unpkg.com/pdfjs-dist@1.9.426/cmaps/';
PDFJS.cMapPacked = true;
var pdfDoc = null;
var canvas = null;
function createPage() {
var div = document.createElement("canvas");
document.body.appendChild(div);
return div;
}
function renderPage(num,aspectRatio) {
if(num > pdfDoc.numPages){
num = num % pdfDoc.numPages;
}
pdfDoc.getPage(num).then(function (page) {
var viewport = page.getViewport(2.0);
if(canvas == null){
canvas = createPage();
}
var ctx = canvas.getContext('2d');
canvas.height = viewport.height;
canvas.width = viewport.width;
page.render({
canvasContext: ctx,
viewport: viewport
});
document.getElementsByTagName('canvas')[0].style.width=aspectRatio+'%';
});
}
PDFJS.getDocument(url).then(function (pdf) {
pdfDoc = pdf;
});
####js调用Android
由于webView存在注入的危险,所以在api17修复这个bug(可以通过java的反射机制可以拿到Runtime对象的引用,并可以调用exec执行命令。),必须在android的方法上面添加@JavaScriptInterface注解,并且在webView调用addJavaScriptInterface()方法,其中有两个参数,第一个参数数你添加@JavaScriptInterface注解方法的类的实例,第二个参数是实例的别名,在js中直接别名.方法名即可调用android中的方法了,示例如下:
Android代码,重点就是最后一句话
public void initView() {
WebSettings webSettings = mVebView.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setPluginState(WebSettings.PluginState.ON);
webSettings.setAllowContentAccess(true);
webSettings.setAllowFileAccess(true);
webSettings.setAllowFileAccessFromFileURLs(true);
// 1. 设置缓存路径 ------ application 缓存
String cacheDirPath = getFilesDir().getAbsolutePath() + "cache/";
webSettings.setAppCachePath(cacheDirPath);
// 2. 设置缓存大小
webSettings.setAppCacheMaxSize(800*1024*1024);
// 3. 开启Application Cache存储机制
webSettings.setAppCacheEnabled(true);
// 开启DOM storage
webSettings.setDomStorageEnabled(true);
webSettings.setSupportZoom(true);
//设置出现缩放工具
webSettings.setBuiltInZoomControls(true);
//设定缩放控件隐藏
webSettings.setDisplayZoomControls(false);
// 只需设置支持JS就自动打开IndexedDB存储机制
webSettings.setJavaScriptEnabled(true);
//根据网络联网情况设置不同的缓存模式
webSettings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
/**
* 简单来说,该项设置决定了JavaScript能否访问来自于任何源的文件标识的URL。
* 比如我们把PDF.js放在本地assets里,然后通过一个URL跳转访问来自于任何URL的PDF,所以这里我们需要将其设置为true。
* 而一般情况下,为了安全起见,是需要将其设置为false的。
*/
webSettings.setAllowUniversalAccessFromFileURLs(true);
mVebView.addJavascriptInterface(this,"oohlink");
}
@JavascriptInterface
public void jsCallAndroid(){
Toast.makeText(this, "js调用android方法", Toast.LENGTH_SHORT).show();
}
js代码如下,同样重点也在代码的最后一句
var url = location.search.substring(1);
PDFJS.cMapUrl = 'https://unpkg.com/pdfjs-dist@1.9.426/cmaps/';
PDFJS.cMapPacked = true;
var pdfDoc = null;
var canvas = null;
function createPage() {
var div = document.createElement("canvas");
document.body.appendChild(div);
return div;
}
function renderPage(num,aspectRatio) {
if(num > pdfDoc.numPages){
num = num % pdfDoc.numPages;
}
pdfDoc.getPage(num).then(function (page) {
var viewport = page.getViewport(2.0);
if(canvas == null){
canvas = createPage();
}
var ctx = canvas.getContext('2d');
canvas.height = viewport.height;
canvas.width = viewport.width;
page.render({
canvasContext: ctx,
viewport: viewport
});
document.getElementsByTagName('canvas')[0].style.width=aspectRatio+'%';
});
}
PDFJS.getDocument(url).then(function (pdf) {
pdfDoc = pdf;
oohlink.jsCallAndroid();
});