Android WebView详解

2023-11-01

一、简介:WebView是一个显示网页的视图。但是它不是一个普通的View,它比一般的View要庞大、复杂,其实它就是一个浏览器,相当于一个Google Chrome,当然它没有Google Chrome本身那么强大。它允许使用浏览器加载网页或者就在WebView内加载网页,早期它是使用WebKit渲染引擎来显示网页,在Android 4.4之后直接是基于chrome,然后chrome又是基于chromium内核。
如果要将Web应用程序(或只是网页)作为客户端应用程序的一部分提供,可以使用WebView进行操作。WebView类是Android的View类的子类,它允许你将网页显示为Activity布局的一部分。它不包括完全开发的Web浏览器的任何功能,例如导航控件或地址栏。默认情况下,所有WebView都会显示一个网页。

二、添加一个WebView到你的应用程序中。
1、在布局文件中添加WebView,方式就是类似于TextView
2、在Java代码中通过findViewById获取到WebView实例
3、webView.loadUrl(“http://www.baidu.com”);
前提:
1、添加上INTERNET权限
2、如果是https,那么这个是需要有官方认证的合法证书,类似于这种自签证书,使用webview去加载,会报错的,无法成功加载。
备注:从内存泄漏和更好的内存管理的角度,最好是在代码中去new一个webview,因为这种在布局文件中添加的方式,可能会因为布局文件的约束导致一定程度的内存泄漏。

三、启用JavaScript

WebView myWebView = (WebView) findViewById(R.id.webview);
WebSettings webSettings = myWebView.getSettings();
webSettings.setJavaScriptEnabled(true);

有些网页如果不启用JavaScript是打开不了的,比如https://www.baidu.com
一般情况下建议启用JavaScript

四、将JavaScript代码绑定到Android代码
在开发专门针对Android应用程序中的WebView设计的Web应用程序时,你可以在JavaScript代码和客户端Android代码之间创建接口。例如,你的JavaScript代码可以调用Android代码中的方法来显示对话框,而不是使用JavaScript的alert()函数。
这里主要用到了addJavascriptInterface方法,详情可以参考
https://developer.android.com/guide/webapps/webview.html#AddingWebView 中的Binding JavaScript code to Android code章节,这里讲的比较详细。
这里我们也根据实际的应用实践,来举一个例子:

    //webviwe init的时候,执行下面这行代码
    mBinding.wv.addJavascriptInterface(new JsInterface(), "android");

    /**
     * 原生与Js交互的回调接口。
     * js端调用android,示例:
     * <button οnclick="android.feedback("gratingAbnormal_new;mouseGuardAbnormal_new")">feedback</button>
     */
    final class JsInterface {
        /**
         * @JavascriptInterface 注解是必须要有的,添加这个注解来将我们定义的方法暴露出去给web端调用。
         * 否则在web端是调用不了的。增加通过注解这个机制也是一种安全保证,否则web端可以随意调用系统方法。
         * 另外方法的修饰符也必须是public,否则web端也访问不了这个方法。
         */
        @JavascriptInterface
        public void feedback(String msg) {
            LogUtils.i("msg:" + msg);
            if (TextUtils.isEmpty(msg)) {
                return;
            }
            mParentAct.runOnUiThread(() -> {
                boolean isGrantingAbnormal = false, isMouseGuardAbnormal = false;
                boolean isGrantingAbnormalNewData = false, isMouseGuardAbnormalNewData = false;
                if (!"normal".equals(msg)) {
                    String[] flagArr = msg.split(";");
                    for (String flag : flagArr) {
                        if (flag.startsWith("gratingAbnormal")) {
                            isGrantingAbnormal = true;
                            if (flag.endsWith("_new")) {
                                isGrantingAbnormalNewData = true;
                            }
                        } else if (flag.startsWith("mouseGuardAbnormal")) {
                            isMouseGuardAbnormal = true;
                            if (flag.endsWith("_new")) {
                                isMouseGuardAbnormalNewData = true;
                            }
                        }
                    }
                }
                mParentAct.mEnvironmentalAlarmController.mGrantingAbnormal = isGrantingAbnormal;
                mParentAct.mEnvironmentalAlarmController.mMouseGuardAbnormal = isMouseGuardAbnormal;
                mParentAct.mEnvironmentalAlarmController.mGrantingAbnormalNewData = isGrantingAbnormalNewData;
                mParentAct.mEnvironmentalAlarmController.mMouseGuardAbnormalNewData = isMouseGuardAbnormalNewData;
                mParentAct.mEnvironmentalAlarmController.environmentalAlarm();
            });
        }
    }

五、处理页面导航
如果想让所有链接都在WebView中实现,可以这样写:

WebView myWebView = (WebView) findViewById(R.id.webview);
myWebView.setWebViewClient(new WebViewClient());

如果想做详细的控制,比如让外链通过浏览器访问,则这样写:

webView.setWebViewClient(new WebViewClient() {
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                if (Uri.parse(url).getHost().equals("https://www.baidu.com")) {
                    return false;
                }
                /**
                 * 外链调用浏览器  往往这样是出于安全考虑
                 */
                Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
                startActivity(intent);
                return true;
            }
        });

六、导航网页历史
当你的WebView覆盖URL加载时,它会自动累积访问的网页的历史记录。你可以通过goBack()和goForward()向后和向前浏览历史记录。
例如,对用户点击手机上的物理返回键的处理如下:

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
    // Check if the key event was the Back button and if there's history
    if ((keyCode == KeyEvent.KEYCODE_BACK) && myWebView.canGoBack()) {
        myWebView.goBack();
        return true;
    }
    // If it wasn't the Back key or there's no web page history, bubble up to the default
    // system behavior (probably exit the activity)
    return super.onKeyDown(keyCode, event);
}

七、加载缓冲条

webView.setWebChromeClient(new WebChromeClient(){  
            @Override  
            public void onProgressChanged(WebView view, int newProgress) {  
                super.onProgressChanged(view, newProgress);  
                progress.setVisibility(View.VISIBLE);  
                progress.setProgress(newProgress);  
            }  
        });
webView.setWebViewClient(new WebViewClient(){   
            @Override  
            public void onPageFinished(WebView view, String url) {  
                super.onPageFinished(view, url);  
                if (progress != null) {  
                    progress.setVisibility(View.GONE);  
                }  
            }  
        });  

八、WebView的缓存
缓存模式:
LOAD_CACHE_ONLY:不使用网络,只读取本地缓存数据。
LOAD_DEFAULT:如果页面没有强制任何特定行为(依赖服务端控制),如果本地有未过期的缓存,就会直接加载本地缓存,否则就请求网络。
LOAD_NORMAL:API level 17中已经废弃, 从API level 11开始作用同LOAD_DEFAULT模式。
LOAD_NO_CACHE:忽略本地缓存(就算有也不用),直接请求网络。
LOAD_CACHE_ELSE_NETWORK:只要本地有缓存,不管有没有过期,都使用本地缓存。否则就请求网络。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android WebView详解 的相关文章

随机推荐

  • Nessus安装与使用

    目录 前言 一 kali安装Nessus 1 访问Nessus官网 2 安装Nessus程序 3 启动Nessus 4 浏览器访问nessus的web网站 5 选择 Managed Scanner 选项 点击 Continue 6 选择 T
  • SPEC CPU简介和使用

    前言 SPEC CPU是一套行业标准的CPU密集型基准测试套件 SPEC设计了此套件 以使用实际用户应用程序开发的工作负载 在最广泛的实际硬件范围内提供计算密集型性能的比较度量 这些基准作为源代码提供 要求用户习惯使用编译器命令以及通过控制
  • Linux开启查看端口

    1 查看防火墙状态 systemctl status firewalld 下图是防火墙关闭状态 2 开启防火墙 systemctl start firewalld 开启端口 firewall cmd zone public add port
  • 教你如何保存有妖气漫画

    有妖气是中国唯一且最大的纯原创漫画网站 官方这么介绍的 是不是真的我也不知道 但是在有妖气中看到喜欢的漫画想要保存下来的时候就出现问题了 有妖气为了防盗版是禁止图片另存为的 如果想要保存漫画只能靠截图了 但是截图后的漫画就没有原版的那么清晰
  • Windows本机无法访问VMware虚拟机Ubuntu上部署的项目

    问题 本机无法访问虚拟机上部署的项目 原因 8080端口没有开放 本来以为防火墙关闭就不会有这个问题 解决方法 开放端口8080 执行命令如下 永久开放8080端口 root ubuntu sudo firewall cmd permane
  • spring boot学习(十四):整合shiro

    shiro和SpringSecurity一样的安全 主要是涉及到realm Spring Boot 的shiro整合
  • S3使用rest API进行签名文件上传出现403问题

    问题 在使用s3的rest api进行签名请求头文件上传的时候 代理服务器出现了403问题 原因 必须将指定的所有签名请求头 都带给aws的s3服务器才能正常返回200响应 如下为请求头信息 POST 86 1792 19 012 0100
  • 【Cocos2d-html5游戏引擎学习笔记(6)】自定义Cocos2d-html5加载资源Loading界面

    这一篇其实本该放在后面写的 只是今天正好把这个整出来了 所以为了防止后面忘记 就在这里先写了 在运行index html文件的时候 引擎首先会把资源进行加载 这是为了让游戏在运行时更为流畅 避免了在运行时加载资源 而出现卡顿现象 影响用户体
  • 自己搭建一个SSH框架

    自己搭建一个SSH框架 真累挺 来源 张成法的日志 1 实验环境准备 MyEclipse8 6 Tomcat6 0 20 MySQL5 1 数据库脚本程序CREATE TABLE user id int 11 NOT NULL auto i
  • 面试题篇-13-Kafka相关面试题

    文章目录 1 什么是消息队列 2 kafka 的零拷贝原理 3 Kafka 如何保证消息不丢失 3 1 Producer 端 3 2 Broker 端 3 3 Consumer 4 Kafka 怎么避免重复消费 5 什么是 ISR 为什么需
  • 图像配准(匹配)与变化检测

    文章目录 简介 A Survey on Deep Learning Based Change Detection from High Resolution Remote Sensing Images 2022 变化检测的基本框架 基于神经网
  • idea好用插件集合

    idea好用插件 1 查看本地是否有未提交代码 2 MybatisX 小鸟插件 3 Nyan Progress Bar 加载彩虹显示插件 4 Translation 翻译插件 5 Tabnine AI Code 代码提示插件 6 Rainb
  • unity限制相机可移动区域(box collider)

    1 创建一个空对象并命名为box 什么名字都可以 但要与代码中的一致 2 选中box在属性面板点击add component添加一个box collider组件 3 把box collider的大小设置到你想限制的区域范围大小 我直接设置成
  • 服务器网页压缩图片,iOS 压缩图片成二进制流上传服务器、从服务器请求下来的二进制流图片展示到页面上...

    iOS中两种压缩图片的方法 将UIImage转化为NSData 可用来上传服务器 UIImagePNGRepresentation UIImage UIImageJPEGRepresentation UIImage CGFloat 前者只有
  • 浪潮NF5280M4使用IPMI安装操作系统

    其实也可以使用U盘安装的 但是由于这次没有U盘 所以使用了IPMI的方式 登录IPMI 如果你不知道IPMI的地址 你需要用KVM连接上服务器 为IPMI配置一个地址 然后把你的电脑地址修改为合IPMI同一 一个网段 打开浏览器进行访问 进
  • Base64和图片之间的转换,及压缩-java(base64字符串最好代码生成,网页工具存在空格问题)

    1 图片转base64String public static BufferedImage photoToBase644 String url String result try File file new File url File fi
  • SourceTree 合并分支上的多个提交,一次性合并分支的多次提交至另一分支,主分支前进时的合并冲突解决

    SourceTree 合并分支上的多个提交 一次性合并分支的多次提交至另一分支 主分支前进时的合并冲突解决 目录 SourceTree 合并分支上的多个提交 一次性合并分支的多次提交至另一分支 主分支前进时的合并冲突解决 1 合并分支上的多
  • 1143. 最长公共子序列 -- 动规

    1143 最长公共子序列 class LongestCommonSubsequence2 1143 最长公共子序列 https leetcode cn problems longest common subsequence def solu
  • Git高级篇(1.3w字)

    学习笔记 插图如果侵权请联系博主删除 1 什么是分支 开发软件时 可能有多个人同时为同一个人软件开发功能或修复BUG 可能存在多个Release版本 并且需要对各个版本进行维护 Git分支功能可以支持同时进行多个功能的开发和版本管理 分支是
  • Android WebView详解

    一 简介 WebView是一个显示网页的视图 但是它不是一个普通的View 它比一般的View要庞大 复杂 其实它就是一个浏览器 相当于一个Google Chrome 当然它没有Google Chrome本身那么强大 它允许使用浏览器加载网