深入理解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…...
ES6从入门到精通:前言
ES6简介 ES6(ECMAScript 2015)是JavaScript语言的重大更新,引入了许多新特性,包括语法糖、新数据类型、模块化支持等,显著提升了开发效率和代码可维护性。 核心知识点概览 变量声明 let 和 const 取代 var…...
云计算——弹性云计算器(ECS)
弹性云服务器:ECS 概述 云计算重构了ICT系统,云计算平台厂商推出使得厂家能够主要关注应用管理而非平台管理的云平台,包含如下主要概念。 ECS(Elastic Cloud Server):即弹性云服务器,是云计算…...
c++ 面试题(1)-----深度优先搜索(DFS)实现
操作系统:ubuntu22.04 IDE:Visual Studio Code 编程语言:C11 题目描述 地上有一个 m 行 n 列的方格,从坐标 [0,0] 起始。一个机器人可以从某一格移动到上下左右四个格子,但不能进入行坐标和列坐标的数位之和大于 k 的格子。 例…...

智能在线客服平台:数字化时代企业连接用户的 AI 中枢
随着互联网技术的飞速发展,消费者期望能够随时随地与企业进行交流。在线客服平台作为连接企业与客户的重要桥梁,不仅优化了客户体验,还提升了企业的服务效率和市场竞争力。本文将探讨在线客服平台的重要性、技术进展、实际应用,并…...
JDK 17 新特性
#JDK 17 新特性 /**************** 文本块 *****************/ python/scala中早就支持,不稀奇 String json “”" { “name”: “Java”, “version”: 17 } “”"; /**************** Switch 语句 -> 表达式 *****************/ 挺好的ÿ…...

SpringCloudGateway 自定义局部过滤器
场景: 将所有请求转化为同一路径请求(方便穿网配置)在请求头内标识原来路径,然后在将请求分发给不同服务 AllToOneGatewayFilterFactory import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; impor…...

USB Over IP专用硬件的5个特点
USB over IP技术通过将USB协议数据封装在标准TCP/IP网络数据包中,从根本上改变了USB连接。这允许客户端通过局域网或广域网远程访问和控制物理连接到服务器的USB设备(如专用硬件设备),从而消除了直接物理连接的需要。USB over IP的…...
Fabric V2.5 通用溯源系统——增加图片上传与下载功能
fabric-trace项目在发布一年后,部署量已突破1000次,为支持更多场景,现新增支持图片信息上链,本文对图片上传、下载功能代码进行梳理,包含智能合约、后端、前端部分。 一、智能合约修改 为了增加图片信息上链溯源,需要对底层数据结构进行修改,在此对智能合约中的农产品数…...
C++.OpenGL (20/64)混合(Blending)
混合(Blending) 透明效果核心原理 #mermaid-svg-SWG0UzVfJms7Sm3e {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-icon{fill:#552222;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-text{fill…...

如何更改默认 Crontab 编辑器 ?
在 Linux 领域中,crontab 是您可能经常遇到的一个术语。这个实用程序在类 unix 操作系统上可用,用于调度在预定义时间和间隔自动执行的任务。这对管理员和高级用户非常有益,允许他们自动执行各种系统任务。 编辑 Crontab 文件通常使用文本编…...