IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> Android WebView使用总结 -> 正文阅读

[移动开发]Android WebView使用总结

#.简介:

?? ?WebView是Android提供的用来展示展示web页面的View,内部使用webkit浏览器引擎(一个轻量级的浏览器引擎),除了展示Web页面外,还可与Web页面内的JS脚本交互调用。

#一、WebView常用方法

1.加载Url或资源的方法

        //方式1:加载指定Url,可以指向网络资源,也可以是本地资源。这是最常用的加载方法。
??????? webView.loadUrl("百度一下,你就知道");
????????webView.loadUrl("file:///xxx/xxx/test.html");
????????//方式2:加载内容片段
?? ??? ?loadData(String data, String mimeType, String encoding);
?? ??? ?loadDataWithBaseURL(String baseUrl, String data, String mimeType, String encoding, String historyUrl));
?
注意:Android9.0之后,默认情况下是禁用明文支持的,因为默认是无法加载Http协议类型的Url的,加载时会报错:net:ERR_CLEARTEXT_NOT_PERMITTED。可以 把Http协议类型的Url换成对应的Https协议类型Url。
?? ?如果要支持加载Http类型的Url,需要在AndroidManifest.xml中
<application> </application>节点下添加配置:? android:usesCleartextTraffic="true"

2.生命周期相关方法

??????? /*2.生命周期相关方法
??????????? 一般会根据所在页面的生命周期变化,来调用以下相关方法*/
??????? //2.1激活WebView实例为活跃状态,能正常执行网页的响应
??????? webView.onResume();

??????? //2.2通知WebView实例的内核暂停所有的动作,如页面解析、插件加载、JavaScript脚本执行等。
??????? //一般当页面被失去焦点被切换到后台不可见状态,需要执行onPause
??????? webView.onPause();

??????? //2.3暂停应用中所有webview的layout、parsing、javascriptTimer等,降低CPU功耗。
??????? //一般当应用被切换到后台时,调用该方法,作用于所有WebView
??????? webView.pauseTimers();
??????? //2.4恢复调用pauseTimers()后被暂停的状态
??????? webView.resumeTimers();

??????? //2.5销毁WebView实例
??????? //注意:为避免出错,要先把WebView从所在View树上移除,再销毁WebView实例
??????? rootLayout.removeView(webView);
??????? webView.destroy();

3.页面前进、后退

??????? /*3.页面前进、后退*/
??????? //是否可以后退
??????? webview.canGoBack();
??????? //后退一页
??????? webview.goBack();

??????? //是否可以前进
??????? webview.canGoForward();
??????? //前进一页
??????? webview.goForward();

??????? //以当前的index为起始点前进或者后退到历史记录中指定的steps
??????? //如果steps为负数则为后退,正数则为前进
??????? webview.goBackOrForward(steps);

4.事件拦截

??????? /*4.事件拦截
??????????? 有很多相关的方法,下面是几个例子*/
??????? //例如覆写按键事件,onKeyDown()/onKeyUp()
??????? @Override
??????? public boolean onKeyDown(int keyCode, KeyEvent event) {
??????????? //示例:点击返回按钮后,默认是触发Activity的finish。若需要触发网页回退,可以添加代码:
??????????? if ((keyCode == KEYCODE_BACK) && mWebView.canGoBack()) {
??????????????? mWebView.goBack();
??????????????? return true;
??????????? }
??????????? return super.onKeyDown(keyCode, event);
??????? }

??????? @Override
??????? public boolean onKeyUp(int keyCode, KeyEvent event) {
??????????? return super.onKeyUp(keyCode, event);
??????? }

5.设置回调接口

?? ??? ?/*5.设置回调接口
??????????? 有很多可设置的接口,下面是个例子*/
??????? //设置下载监听接口
??????? webView.setDownloadListener(new DownloadListener() {
??????????? @Override
??????????? public void onDownloadStart(String url, String userAgent, String contentDisposition, String mimetype, long contentLength) {
???????????????
??????????? }
??????? });

6.其它方法

?? ?/*6.其它方法*/
?? ?//刷新页面(当前页面的所有资源都会重新加载)
?? ?webView.reload();
?? ?//停止加载
?? ?webView.stopLoading();
?? ?//清除整个应用中WebView网页访问留下的缓存
?? ?webView.clearCache(true);
?? ?//清除对应WebView访问的历史记录
? ? webview.clearHistory();
?? ?//清除当前WebView自动完成填充的表单数据(并不会清除WebView存储到本地的数据)
? ? webview.clearFormData();

#二、常用的辅助类:WebSetting/WebViewClient/WebChromeClient

?? ?WebView内部的WebSetting对象负责管理WebView的参数配置;
?? ?WebViewClient负责处理WebView的各种请求和通知事件,在对应事件发生时会执行WebViewClient的对应回调;
?? ?WebChromeClient辅助Webview处理与JS一些交互功能,主要是提供一些标准的回调方法,当JS调用相关方法时会触发对应回调。? ??

##1. 通过WebSetting设置参数

?? ?WebView内部的WebSetting对象负责管理WebView的配置,WebSetting提供了一系列方法来供开发者来做配置。
?? ?以下将这些参数分为了三大类:显示相关的、缓存和存储相关的、其它相关,在下面代码和注释中详细列举出了。
其中缓存模式,一共可设置四种:
????????LOAD_CACHE_ONLY: 不使用网络,只读取本地缓存数据
????????LOAD_DEFAULT: (默认)根据cache-control决定是否从网络上取数据。
????????LOAD_NO_CACHE: 不使用缓存,只从网络获取数据.
????????LOAD_CACHE_ELSE_NETWORK,只要本地有,无论是否过期,或者no-cache,都使用缓存中的数据。
//0.获取WebSettings对象,通过WebView的getSettings()
WebSettings webSettings = getSettings();
if (null != webSettings) {
??? /*1.显示效果相关设置:页面缩放、页面自适应等等*/
??? //1.1设置自适应屏幕,两者合用
??? webSettings.setLoadWithOverviewMode(true); //缩放至屏幕的大小
??? webSettings.setUseWideViewPort(true); //将图片调整到适合webview的大小
??? //1.2缩放操作
??? //支持缩放,默认为true。是下面几项设置的的前提
??? webSettings.setSupportZoom(true);
??? //设置内置的缩放控件。若为false,则该WebView不可缩放
??? webSettings.setBuiltInZoomControls(true);
??? webSettings.setDisplayZoomControls(false); //隐藏原生的缩放控件
??? //1.3其它
??? webSettings.setLoadsImagesAutomatically(true); //支持自动加载图片
??? webSettings.setSupportMultipleWindows(false);//是否支持多窗口
??? //设置布局,会引起WebView的重新布局(relayout),默认值NARROW_COLUMNS
??? webSettings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NARROW_COLUMNS);

??? /*2.缓存、数据存储、缓存加载相关设置*/
??? //2.1缓存相关
??? /* webSettings.setCacheMode()可设置缓存模式,一共可设置四种缓存模式:
??????? LOAD_CACHE_ONLY: 不使用网络,只读取本地缓存数据
??????? LOAD_DEFAULT: (默认)根据cache-control决定是否从网络上取数据。
??????? LOAD_NO_CACHE: 不使用缓存,只从网络获取数据.
??????? LOAD_CACHE_ELSE_NETWORK,只要本地有,无论是否过期,或者no-cache,都使用缓存中的数据。
??????? 可结合使用(离线加载)
??????? if (有网络) {
??????????? webSettings.setCacheMode(WebSettings.LOAD_DEFAULT);//根据cache-control决定是否从网络上取数据。
??????? } else {
??????????? webSettings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);//没网,则优先从本地获取,即离线加载
??????? }*/
??? //设置缓存的模式,这里设置的模式为默认模式,即根据cache-control决定是否从网络上取数据
??? webSettings.setCacheMode(WebSettings.LOAD_NO_CACHE);
??? //开启应用缓存,默认值false
??? webSettings.setAppCacheEnabled(true);
??? //设置应用缓存文件路径
??? webSettings.setAppCachePath(getContext().getDir("appcache", 0).getPath());
??? //设置应用缓存内容的最大值
??? webSettings.setAppCacheMaxSize(Long.MAX_VALUE);
??? //3.2其它
??? //开启数据库存储API功能
??? webSettings.setDatabaseEnabled(true);
??? //设置数据库的存储路
??? webSettings.setDatabasePath(getContext().getDir("databases", 0).getPath());
??? webSettings.setAllowFileAccess(true); //设置允许访问文件系统
??? webSettings.setDomStorageEnabled(true);//开启DOM存储API功能

??? /*3.其它设置*/
??? //3.1 js脚本、插件相关设置
??? //设置为支持Javascript,此时可与页面中的js脚本交互
??? webSettings.setJavaScriptEnabled(true);
??? //支持通过JS打开新窗口
??? webSettings.setJavaScriptCanOpenWindowsAutomatically(true);
??? //3.2加载模式
??? //Android5.0开始,WebView默认不支持同时加载Https和Http混合模式
??? //此处设置为支持混合模式
??? if (Build.VERSION.SDK_INT >= 21) {
??????? webSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
??? }
??? //3.3其它
??? webSettings.setDefaultTextEncodingName("utf-8");//设置编码格式
??? webSettings.setRenderPriority(WebSettings.RenderPriority.HIGH);? //提高渲染的优先级
??? webSettings.setGeolocationEnabled(true);// 启用地理定位
??? webSettings.setGeolocationDatabasePath(getContext().getDir("geolocation", 0).getPath());//设置定位的数据库路径
??? //设置WebView的用户代理字符串,网页端可获取到该字符串从而判断客户端类型,应该按照与web端约定的规则生成。
??? //如果字符串为null或者empty,将使用系统默认值。
??? webSettings.setUserAgentString(webSettings.getUserAgentString() + DeviceUtils.getUserAgent());
}

##2.设置WebViewClient

?? ?WebViewClient负责处理WebView的各种请求和通知事件,在对应事件发生时会执行WebViewClient的对应回调。例如URL加载重定向、网页开始加载/加载完毕、各种错误通知等。
? ? 常用方法与接收,见以下代码示例与注释。
/**
* 按照doc中注释说明,当WebView不设置WebViewClient时,加载Url时默认会选择系统中合适的Activity来打开该Url。
* 当设置WebViewClient时,加载Url默认会执行到该方法,可在内部做相应处理。
*?? 返回true时,意味着应用已经拦截并处理了本次加载事务,WebView后继将不再处理;
*?? 返回false时,意味着应用未拦截本次加载事务,后继WebView将加载该Url
* 注意:POST请求不会触发该方法
*
* 可以在这该方法进行各种判断,例如约定好好各种类型操作的Url格式,解析Url格式和参数
*? 来判断是去打开特定Activity执行特定操作,还是加载Url对应网页
* @param view
* @param url
* @return
*/
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
??? //可以在这里进行各种判断,例如定义好各种url格式,解析url格式和参数
??? // 来判断是去打开特定Activity执行特定操作,还是加载url对应网页
??? return false;
}

/**
* 当开始加载Url时回调
*/
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
??? super.onPageStarted(view, url, favicon);
}

/**
* 页面加载完毕时回调
*/
@Override
public void onPageFinished(WebView view, String url) {
??? super.onPageFinished(view, url);
}

/**
* 在即将加载网络请求之前回调,可拦截返回自定义的资源作为请求结果,让WebView来加载
*/
@Override
public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
??? return super.shouldInterceptRequest(view, request);
}

/**
* 当WebView显示内容发生放缩时回调
*/
@Override
public void onScaleChanged(WebView view, float oldScale, float newScale) {
??? super.onScaleChanged(view, oldScale, newScale);
}

/**
* 访问Url出错时回调
*/
@Override
public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
??? super.onReceivedError(view, request, error);
}

/**
* 当网页加载资源过程中发现SSL错误时回调。
* 可执行的操作:handler.cancel(),取消请求;
*??????????? handler.proceed(),继续请求;
* 默认的逻辑时取消请求。
* @param view
* @param handler
* @param error
*/
@Override
public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
??? String url = null;
??? if (error != null) {
??????? url = error.getUrl();
??? }
??? if (!TextUtils.isEmpty(url)) {
??????? handler.proceed();
??? } else {
??????? super.onReceivedSslError(view, handler, error);
??? }
}

##3.WebChromeClient

?? ?辅助Webview处理与JS一些交互功能,主要是提供一些标准的回调方法,当JS调用相关方法时会触发对应回调。
?? ?除此之外,还可以获取网页加载进度和网页标题等。
一些API方法示例:
/**
 *  获取网页标题,
 *  加载网页时会触发该方法,并把网页标题作为参数传入
 */
@Override
public void onReceivedTitle(WebView view, String title) {
    super.onReceivedTitle(view, title);
}

/**
 *  通过该方法,可获取网页当前的加载进度。在网页加载过程中会多次被触发,传入当前已加载的百分比。
 */
@Override
public void onProgressChanged(WebView view, int newProgress) {
    super.onProgressChanged(view, newProgress);
}

/**
 * 网页中JS脚本调用prompt()时触发该回调,一般用作提示
 */
@Override
public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) {
    return super.onJsPrompt(view, url, message, defaultValue, result);
}

/**
 * 网页中JS脚本调用alert()时触发该回调,一般用作警告
 */
@Override
public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
    return super.onJsAlert(view, url, message, result);
}

/**
 * 网页中JS脚本调用confirm()时触发该回调,一般用作确认
 */
@Override
public boolean onJsConfirm(WebView view, String url, String message, JsResult result) {
    return super.onJsConfirm(view, url, message, result);
}

##4. Cookie相关设置

?? ?//Cookie相关设置
?? ?if(Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP){
??? ?? ?CookieSyncManager.createInstance(context);
?? ?}
?? ?CookieManager cookieManager = CookieManager.getInstance();
?? ?cookieManager.setAcceptCookie(true);//允许使用Cookie
?? ?//手动同步Cookie信息
?? ?if (Build.VERSION.SDK_INT < 21) {
??? ?? ?CookieSyncManager.getInstance().sync();
?? ?} else {
??? ?? ?CookieManager.getInstance().flush();
?? ?}

#三、WebView中Java与JS交互的几种方式

#1. Java调用JS

##方法1:使用Webview.loadUrl(“javaScript:【方法名和参数对应的字符串】”);

注:该方法会导致页面刷新
示例:
mWebView.loadUrl( “javascript:callJS()” );
mWebView.loadUrl( “javascript:callJS("+ 【参数变量】 +")” );

##方法2:使用Webview.evaluateJavaScript(“javaScript:【方法名和参数对应的字符串】”);

注:1.该方法不会导致页面刷新? 2.Android4.4之后才能使用该API方法
示例:
//注:在 ValueCallback<String>泛型中的参数类型表明JS函数返回值的类型,该示例中为String类型
mWebView.evaluateJavascript( "javascript:callJS()" , new ValueCallback<String>() {?
?? ? @Override?
?? ? public void onReceiveValue (String value ) {?
?? ??? ? //此处为 js 返回的结果?
?? ? }?
});

#2. JS调用Java

##方法1:通过WebView.addJavascriptInterface(【包含JS接口的Java对象】, 【在JS中的对象名称】);

在JavaScript中映射一个Java对象,该对象包含了各种需要被调用的方法。
使用步骤:
1).声明一个Java类,通过 @JavascriptInterface注解来创建各个需要被JS调用的方法
2).通过 WebView.addJavascriptInterface( 【Java对象】 , “【JS中的对象名称】” )将一个上述Java类对象与 JavaScript中对应名称的对象 建立映射关系
3).在JS中通过指定名称对象调用相关方法,等于调用被映射的Java对象的方法
示例:
public class JSInterface{
??? @JavascriptInterface
??? public void pay(final String json) {
??? }

??? @JavascriptInterface
??? public String getToken() {
??????? return null;
??? }
}

//设置JS接口对应的Java对象
JSInterface jsInterface = new JSInterface();
addJavascriptInterface(jsInterface, "javaObj");
//在JS中,可以用指定的名称"javaObj"来调用Java相应方法

#方法2:通过在JS中加载url, 触发WebView.shouldOverrideUrlLoadding(WebView view,String url)方法,从而在该方法中根据加载的url字符串做相应的逻辑处理。

使用步骤:
????1)当JS中进行url加载时,Android中WebViewClient?的回调方法shouldOverrideUrlLoading()会被触发,拦截相应url
????2)在shouldOverrideUrlLoading()对拦截的url做解析,执行需要执行的对应逻辑。

#方法3:通过在JS中执行各种弹窗操作,来触发WebChromeClient的相应拦截方法,在回调方法中执行需要的逻辑。不推荐该方式,因为这些回调方法在设计上讲,本来不是做这种用途的。

(其思路与方法2相似,也是通过JS中的操作来触发Java中的回调方法,从而在Java回调方法中执行需要执行的逻辑。只不过方法2是通过加载url,来触发WebViewClient的shouldOverrideUrlLoadding()方法;而方法3是通过各种弹窗操作,来触发WebChromeClient的各种回调方法。)
使用步骤,与方法2类似:
? ? 1.在JS中调用弹窗,触发WebChromeClient的相应拦截方法
? ? 2.在Java拦截方法中,通过解析传入的字符参数,来执行相应的逻辑。
JS中常用的弹窗方法由三种:?? ??? ??alert()、confirm()、prompt()
在WebChromeClient中对应触发的拦截方法为:onJsAlert()、onJsConfirm()、onJsPrompt
  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-07-04 23:03:58  更:2022-07-04 23:04:25 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 2:43:12-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码