深入理解Android WebView的加载流程与事件回调
文章目录
- 一、WebView 加载流程时序图
- 二、WebView 加载流程回调函数说明
- 三、`AwContents`
- 3.1 主要功能和职责
- 3.2 架构和实现
- 3.3 使用场景
- 四、利用WebView回调函数检测白屏
- 4.1 使用`onPageStarted`和`onPageFinished`检测加载时间
- 4.2 利用`onReceivedError`和`onReceivedHttpError`检测加载错误
- 4.3 使用`shouldInterceptRequest`监控资源加载
- 4.4 使用`onPageCommitVisible`
- 4.5 结合JavaScript和`evaluateJavascript`
- 五、结论
在Android开发中,WebView
用于显示网页和执行JavaScript。理解其加载流程和事件回调对于开发一个功能丰富且用户友好的基于Web的应用至关重要。本文将详细介绍 WebView
加载一个URL时的整个流程和相关的事件回调,帮助开发者更好地掌握其使用方法和处理可能出现的问题。
一、WebView 加载流程时序图
当用户通过 WebView
加载一个URL时,整个过程涉及多个组件和一系列复杂的交互。下面是一个 WebView
加载URL的时序图,以及对每个回调事件的详细说明。
上面的时序图提供了一个清晰的视图,展示了从开始加载URL到页面加载完成的整个过程中WebView和WebViewClient的交互。每个回调都在特定的时机被触发,以处理不同的事件和状态变化。
二、WebView 加载流程回调函数说明
-
触发加载
用户或应用触发loadUrl()
方法,开始加载指定的URL。 -
原生层处理
WebView
调用其底层实现(通常是AwContents
的nativeLoadUrl()
方法)来开始网络请求。 -
页面加载的各阶段
- 页面加载开始:此时,
WebViewClient
的onPageStarted()
方法被调用,标志着页面加载的开始。 - 资源请求拦截:
shouldInterceptRequest()
方法可能会被多次调用,允许开发者拦截、修改或替换正在加载的资源。 - 资源加载:对于页面上的每个资源(如图片、CSS文件等),
onLoadResource()
方法会被调用。
- 处理特殊事件
在加载过程中,WebView
可能会遇到各种需要特殊处理的情况:
- 表单重提交:
onFormResubmission()
被调用,询问用户是否重新提交表单。 - HTTP认证请求:
onReceivedHttpAuthRequest()
请求HTTP认证信息。 - 客户端证书请求:
onReceivedClientCertRequest()
提供客户端证书。 - SSL错误处理:
onReceivedSslError()
处理SSL验证失败的情况。 - HTTP错误处理:
onReceivedHttpError()
处理HTTP错误响应。 - 重定向过多:
onTooManyRedirects()
处理页面重定向问题。 - 安全浏览命中:
onSafeBrowsingHit()
处理访问到被标记为不安全的网页。
- 页面内容显示
- 页面即将可见:
onPageCommitVisible()
方法被调用,标志着页面内容即将显示在屏幕上。 - 页面加载完成:最终,
onPageFinished()
方法被调用,通知应用页面已完全加载。
每个回调方法都有其特定的用途,例如,shouldOverrideUrlLoading()
允许开发者决定是否拦截URL加载,而 onScaleChanged()
则用于处理缩放事件。正确处理这些回调可以极大地增强应用的功能性和用户体验。
三、AwContents
本节介绍时序图中的AwContents
。AwContents
是 Android WebView 的一个核心组件,它在 Android WebView 架构中扮演着非常重要的角色。AwContents
是 Chromium 项目的一部分,它负责管理 WebView 的内容渲染和事件处理。在 Android 系统中,AwContents
作为 WebView 的底层实现,提供了与 Chromium 引擎的直接交互接口。
3.1 主要功能和职责
-
内容渲染:
AwContents
负责将网页内容渲染到 WebView 组件上。它使用 Chromium 的渲染引擎(Blink)来解析 HTML、CSS 和 JavaScript,确保网页内容能够正确显示。 -
事件处理:
它处理来自上层 WebView 和 WebViewClient 的各种事件和请求,如页面加载、资源请求、导航事件等,并将这些事件转发到 Chromium 引擎。 -
JavaScript 交互:
AwContents
提供了与 JavaScript 代码交互的接口,允许 Android 应用与网页中的 JavaScript 代码进行通信。 -
安全和隐私:
它实现了多种安全措施,如同源策略、内容安全策略等,以保护用户的安全和隐私。 -
网络请求管理:
AwContents
管理所有网络请求,包括图片、CSS 文件、JavaScript 文件等资源的加载。它支持自定义网络请求的处理,例如通过shouldInterceptRequest()
方法拦截和修改请求。
3.2 架构和实现
AwContents
是一个桥接类,它连接了 Android 的 WebView API 和 Chromium 的底层实现。在 Android WebView 的架构中,AwContents
位于 Java 层和 native 层之间,它通过 JNI(Java Native Interface)与 native 代码进行交互。
在 native 层,AwContents
对应的实现是 content::WebContents
,这是 Chromium 中用于管理网页内容的核心类。WebContents
负责页面的生命周期管理、渲染进程管理和页面内容的实际渲染。
3.3 使用场景
开发者通常不直接与 AwContents
交互,而是通过 WebView
提供的高级 API 来进行开发。然而,了解 AwContents
的工作原理对于解决 WebView 中的高级问题、性能优化以及实现自定义功能非常有帮助。
AwContents
是 Android WebView 中的一个关键组件,它使得 WebView 能够利用 Chromium 引擎的强大功能,提供高性能和高兼容性的网页浏览体验。
四、利用WebView回调函数检测白屏
在Android开发中,使用WebView时偶尔会遇到白屏问题,这通常是由于网页加载不完全、资源加载失败或者JavaScript错误等原因引起的。利用WebView的回调函数可以帮助我们检测并诊断这种白屏问题。以下是一些策略和步骤,展示如何使用WebView的回调函数来检测白屏:
4.1 使用onPageStarted
和onPageFinished
检测加载时间
白屏可能是因为页面加载时间过长。通过记录onPageStarted
和onPageFinished
之间的时间差,可以判断页面是否在合理的时间内完成加载。
webView.setWebViewClient(new WebViewClient() {long startTime;@Overridepublic void onPageStarted(WebView view, String url, Bitmap favicon) {super.onPageStarted(view, url, favicon);startTime = System.currentTimeMillis();}@Overridepublic void onPageFinished(WebView view, String url) {super.onPageFinished(view, url);long loadTime = System.currentTimeMillis() - startTime;if (loadTime > ACCEPTABLE_LOAD_TIME) {// 记录或处理加载时间过长的情况}}
});
4.2 利用onReceivedError
和onReceivedHttpError
检测加载错误
这些回调函数可以帮助我们捕获在加载过程中发生的错误,这些错误可能会导致页面内容无法正确显示,从而出现白屏。
webView.setWebViewClient(new WebViewClient() {@Overridepublic void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {super.onReceivedError(view, request, error);// 处理加载错误}@Overridepublic void onReceivedHttpError(WebView view, WebResourceRequest request, WebResourceResponse errorResponse) {super.onReceivedHttpError(view, request, errorResponse);// 处理HTTP错误}
});
4.3 使用shouldInterceptRequest
监控资源加载
如果关键资源(如CSS或JavaScript文件)加载失败,可能会导致页面显示不完整或白屏。通过shouldInterceptRequest
可以监控这些资源的加载情况。
webView.setWebViewClient(new WebViewClient() {@Overridepublic WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {// 检查请求的资源,记录加载失败的资源return super.shouldInterceptRequest(view, request);}
});
4.4 使用onPageCommitVisible
onPageCommitVisible
在页面内容即将显示时调用,如果在这个阶段页面内容为空或不完整,可能是一个白屏的迹象。但是,onPageCommitVisible
回调本身并不能直接提供页面内容的信息,我们需要结合其他方法来实现这个目标。一种可能的方法是在onPageCommitVisible
回调中使用evaluateJavascript
来检查页面的DOM结构。例如,我们可以检查某个关键元素是否存在,或者是否有内容。以下是一个示例:
webView.setWebViewClient(new WebViewClient() {@Overridepublic void onPageCommitVisible(WebView view, String url) {super.onPageCommitVisible(view, url);// 检查页面内容是否可见或部分内容是否缺失view.evaluateJavascript("(function() { return document.getElementById('keyElement').innerHTML; })();", new ValueCallback<String>() {@Overridepublic void onReceiveValue(String value) {if (value == null || value.isEmpty()) {// 如果关键元素不存在或没有内容,那么可能存在白屏问题Log.e("WebView", "Key element is missing or empty");}}});}
});
在这个示例中,我们假设keyElement
是页面中的一个关键元素,我们通过JavaScript代码获取这个元素的内容,然后在回调中检查这个内容是否存在。如果不存在,那么可能存在白屏问题。
实际的检查方法可能需要根据你的具体需求进行调整。例如,你可能需要检查多个元素,或者使用更复杂的JavaScript代码来检查页面的状态。
4.5 结合JavaScript和evaluateJavascript
通过注入JavaScript代码检查DOM元素的存在或内容,可以帮助确认页面是否正确渲染。
webView.evaluateJavascript("(function() { return document.body.innerHTML; })();", new ValueCallback<String>() {@Overridepublic void onReceiveValue(String html) {if (html.isEmpty()) {// 处理白屏情况}}
});
通过上述方法,结合日志记录和异常处理机制,可以有效地检测和诊断WebView中的白屏问题。这些技术不仅可以帮助开发者提高应用的稳定性和用户体验,还可以在开发和测试阶段快速定位问题。
五、结论
WebView
的加载流程涉及复杂的交互和多个阶段,每个阶段都可能触发不同的事件回调。作为开发者,理解这些过程和回调的时机及其作用是非常重要的。这不仅可以帮助我们更有效地使用 WebView
,还可以在开发过程中预见并解决潜在问题,从而创建更加稳定和可靠的应用。
相关文章:

深入理解Android WebView的加载流程与事件回调
文章目录 一、WebView 加载流程时序图二、WebView 加载流程回调函数说明三、AwContents3.1 主要功能和职责3.2 架构和实现3.3 使用场景 四、利用WebView回调函数检测白屏4.1 使用onPageStarted和onPageFinished检测加载时间4.2 利用onReceivedError和onReceivedHttpError检测加…...
机器视觉相机自动对焦算法
第一,Brenner梯度法、 第二,Tenegrad梯度法、 第三,laplace梯度法、 第四,方差法、 第五,能量梯度法。 此实例通过使用Halcon实现5种清晰度算法函数: 1. 方差算法函数; 2. 拉普拉斯能量函数…...

StarTowerChain:开启去中心化创新篇章
官网: www.startower.fr 在当今创新驱动的时代,StarTowerChain 以其独特的去中心化创新模式,为我们带来了新的希望和机遇。去中心化,这个充满活力与创造力的理念,正引领着我们走向未来的创新之路。 StarTowerChain …...

SpringCloudStream使用StreamBridge实现延时队列
利用RabbitMQ实现消息的延迟队列 一、安装RabbitMQ 1、安装rabbitmq 安装可以看https://blog.csdn.net/qq_38618691/article/details/118223851,进行安装。 2、安装插件 安装完毕后,exchange是不支持延迟类型的,需要手动安装插件,需要和安装的rabbitmq版本一致 https:…...
MATLAB中head函数用法
目录 语法 说明 示例 显示矩阵的前八行 显示表的前三行 返回表的前八行 head函数的功能是获取数组或表的顶行。 语法 head(A) head(A,k) B head(___) 说明 head(A) 在命令行窗口中显示数组、表或时间表 A 的前八行,但不存储值。 head(A,k) 显示 A 的前 k …...
golang 基本数据类型
1. go语言的数据类型简介 golang的数据类型分为两大类,一类是基本数据类型和符合数据类型; 按照传递的内容分:传递本身数据和传递地址; golang和java很相似,都是值传递,不过分为传递的值和传递的地址&a…...

各种查询sql介绍
1. 关联查询(JOIN) 关联查询用于从多个表中检索数据。它基于两个或多个表之间的共同字段(通常是主键和外键)来组合数据。 内连接(INNER JOIN): sql SELECT a.name, b.order_date FROM custome…...
Guava防击穿回源-异步防击穿
异步防击穿策略 在高并发环境下,缓存击穿(Cache Stampede)是一种常见的问题。当缓存中的热点数据失效或未命中时,大量并发请求同时访问后端数据源(如数据库),可能导致后端系统压力骤增,甚至出现崩溃。为了有效防止这种情况,可以利用Guava提供的异步缓存加载机制(类似…...

人工智能正在扼杀云计算的可持续性
可持续性曾是公共云计算中备受推崇的优势。企业和云提供商大肆宣扬他们的绿色计划,推广采用可再生能源的数据中心,以减少碳足迹。 近几个月来,这个话题已悄然淡出人们的视线。罪魁祸首是什么?对人工智能功能的无限需求正在推动云…...

C# 条形码、二维码标签打印程序
1、条码标答打印主界面 2、打印设置 3、生成QR代码 private void GetBarcode_T(string lr) { QRCodeEncoder qrCodeEncoder = new QRCodeEncoder();//创建一个对象 qrCodeEncoder.QRCodeEncodeMode = QRCodeEncoder.ENCODE_MODE.BYTE; //设置编码测量…...

嵌入式入门学习——6Protues点亮数码管,认识位码和段码,分辨共阴还是共阳(数字时钟第一步)
0 系列文章入口 嵌入式入门学习——0快速入门,Let‘s Do It! 首先新建基于Arduino UNO的protues工程,见本系列第3篇文章 1 点“P”按钮找器件 2 输入“seg”或“digit”查找数码管器件 3 找到我们想要的6位7段数码管 4如图A、B…DP都是段码…...

poisson过程——随机模拟(Python和R实现)
Python实现 exponential()使用,自动poisson过程实现。 import numpy as np import matplotlib.pyplot as plt# Parameters lambda_rate 5 # rate parameter (events per time unit) T 10 # total time# Generate Poisson process times np.random.exponential(…...

100 种下划线 / 覆盖层动画 | 终极 CSS(层叠样式表)集合
还在为你的菜单项和链接寻找动画效果而感到疲惫吗? 不用再找了!这里列出了 100 多种不同的动画。从简单的到更复杂的,你肯定能找到自己想要的。 无需 SVG(可缩放矢量图形),无需 JavaScript(脚…...

华为ICT大赛2024-2025网络赛道考试分析
华为ICT大赛2024-2025正在报名中,网络赛道的同学如何备考,了解考试内容呢? 一、考试概况 华为ICT大赛分为4个赛段,分别为省赛初赛、省赛复赛、中国总决赛,全球总决赛。其中对应的能力级别分别如下: 省赛…...

linux 效率化 - 输入法 - fcitx5
安装 Fcitx5 1. 卸载 ibus 框架 由于 ibus 和 fcitx 可能会冲突,先卸载 ibus(暂未确认原因) sudo apt remove --purge ibus2. 安装 fcitx5 输入法框架 sudo apt update sudo apt install fcitx5 fcitx5-chinese-addons fcitx5-frontend-gtk…...
YOLOv11改进策略【卷积层】| 替换骨干网络 CVPR-2024 RepViT 轻量级的Vision Transformers架构
一、本文介绍 本文记录的是基于RepVit的YOLOv11轻量化改进方法研究。RepVit的网络结构借鉴ViT的设计理念,通过分离的token mixe和channel mixer减少推理时的计算和内存成本,同时减少扩展比率并增加宽度,降低延迟,并通过加倍通道来弥补参数大幅减少的问题,提高了准确性。本…...
一天认识一个硬件之路由器
今天来给大家分享一下路由器的知识,先来说一下什么是路由器,路由器是一种计算机网络设备,它的主要作用是在不同的网络之间转发数据包,实现数据的传输和共享,介绍完了什么是路由器,再来介绍一下路由器的定义…...

【scene_manager】与 MoveIt 机器人的规划场景进行交互
scene_manager Scene Manager包是由 Robotnik 创建的 ROS 包,旨在帮助构建和与 MoveIt 机器人的规划场景进行交互。 背景信息 MoveIt 规划场景 是一个用于存储机器人周围世界的表示(外部碰撞)以及机器人自身状态(内部碰撞和当…...

数据结构单向链表的插入和删除(一)
链表 一、链表结构: (物理存储结构上不连续,逻辑上连续;大小不固定)二、单链表:三、单项链表的代码实现:四、开发可用的链表:四、单链表的效率分析: 一、链表结构&#x…...

鸿蒙网络编程系列30-断点续传下载文件示例
1. 断点续传简介 在文件的下载中,特别是大文件的下载中,可能会出现各种原因导致的下载暂停情况,如果不做特殊处理,下次还需要从头开始下载,既浪费了时间,又浪费了流量。不过,HTTP协议通过Range…...

【JavaEE】-- HTTP
1. HTTP是什么? HTTP(全称为"超文本传输协议")是一种应用非常广泛的应用层协议,HTTP是基于TCP协议的一种应用层协议。 应用层协议:是计算机网络协议栈中最高层的协议,它定义了运行在不同主机上…...
从零实现富文本编辑器#5-编辑器选区模型的状态结构表达
先前我们总结了浏览器选区模型的交互策略,并且实现了基本的选区操作,还调研了自绘选区的实现。那么相对的,我们还需要设计编辑器的选区表达,也可以称为模型选区。编辑器中应用变更时的操作范围,就是以模型选区为基准来…...

【机器视觉】单目测距——运动结构恢复
ps:图是随便找的,为了凑个封面 前言 在前面对光流法进行进一步改进,希望将2D光流推广至3D场景流时,发现2D转3D过程中存在尺度歧义问题,需要补全摄像头拍摄图像中缺失的深度信息,否则解空间不收敛…...

转转集团旗下首家二手多品类循环仓店“超级转转”开业
6月9日,国内领先的循环经济企业转转集团旗下首家二手多品类循环仓店“超级转转”正式开业。 转转集团创始人兼CEO黄炜、转转循环时尚发起人朱珠、转转集团COO兼红布林CEO胡伟琨、王府井集团副总裁祝捷等出席了开业剪彩仪式。 据「TMT星球」了解,“超级…...
【Web 进阶篇】优雅的接口设计:统一响应、全局异常处理与参数校验
系列回顾: 在上一篇中,我们成功地为应用集成了数据库,并使用 Spring Data JPA 实现了基本的 CRUD API。我们的应用现在能“记忆”数据了!但是,如果你仔细审视那些 API,会发现它们还很“粗糙”:有…...
WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)
一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解,适合用作学习或写简历项目背景说明。 🧠 一、概念简介:Solidity 合约开发 Solidity 是一种专门为 以太坊(Ethereum)平台编写智能合约的高级编…...

NXP S32K146 T-Box 携手 SD NAND(贴片式TF卡):驱动汽车智能革新的黄金组合
在汽车智能化的汹涌浪潮中,车辆不再仅仅是传统的交通工具,而是逐步演变为高度智能的移动终端。这一转变的核心支撑,来自于车内关键技术的深度融合与协同创新。车载远程信息处理盒(T-Box)方案:NXP S32K146 与…...

Axure 下拉框联动
实现选省、选完省之后选对应省份下的市区...

【深度学习新浪潮】什么是credit assignment problem?
Credit Assignment Problem(信用分配问题) 是机器学习,尤其是强化学习(RL)中的核心挑战之一,指的是如何将最终的奖励或惩罚准确地分配给导致该结果的各个中间动作或决策。在序列决策任务中,智能体执行一系列动作后获得一个最终奖励,但每个动作对最终结果的贡献程度往往…...
Java详解LeetCode 热题 100(26):LeetCode 142. 环形链表 II(Linked List Cycle II)详解
文章目录 1. 题目描述1.1 链表节点定义 2. 理解题目2.1 问题可视化2.2 核心挑战 3. 解法一:HashSet 标记访问法3.1 算法思路3.2 Java代码实现3.3 详细执行过程演示3.4 执行结果示例3.5 复杂度分析3.6 优缺点分析 4. 解法二:Floyd 快慢指针法(…...