文章目录
博客代码 :
- GitHub : https://github.com/han1202012/WebViewDemo
- CSDN :
一、Android WebView 设置
1、设置 WebSettings
设置 WebSettings 前 , 要先获取 WebSettings 实例对象 , 调用 WebView#getSettings 函数 , 可以获取该 WebSettings 实例对象 ;
// 获取并设置 Web 设置
val settings = webview.settings
启用 JavaScript
设置 WebView 是否 启用 JavaScript 代码执行 ;
该选项必须启用 , 否则大部分网页都无法使用 ;
settings.javaScriptEnabled = true // 支持 JavaScript
启用 DOM 存储
DOM 存储是一种 在 Web 应用程序中存储数据的机制,它使用 JavaScript 对象和属性来存储和检索数据 ;
启用 DOM 存储后,Web 应用程序可以 在客户端上存储和检索数据,而 无需向服务器发出请求。这可以 减少网络流量和提高性能,但可能会占用更多的设备存储空间。
如果 Web 应用程序需要在客户端上存储数据以提高性能,那么启用 DOM 存储是一个不错的选择。
启用 DOM 存储可能会占用更多的设备存储空间,因此您应该在必要时使用它,并在不需要时禁用它。
// 设置是否启用 DOM 存储
// DOM 存储是一种在 Web 应用程序中存储数据的机制,它使用 JavaScript 对象和属性来存储和检索数据
settings.domStorageEnabled = true
启用内置缩放控件
设置 WebView 是否 启用内置缩放控件 ;
当 builtInZoomControls 属性设置为 true 时,WebView 将在屏幕上显示一个简单的缩放控件,用户可以使用它来放大或缩小网页。
通过双指捏合手势也可以进行缩放。启用内置缩放控件可以提高用户的体验,使其更容易在移动设备上浏览网页。
如果网页已经自适应了移动设备的屏幕大小并且用户可以通过双指捏合手势来缩放网页,那么不需要启用此选项。
// 设置 WebView 是否启用内置缩放控件 ( 自选 非必要 )
settings.builtInZoomControls = true
当使用双指捏合缩放时 , 右下角就会出现下面的缩放控件 ;
启用 http 和 https 混合加载
设置 WebView 是否允许加载来自不安全来源的混合内容。 混合内容是指 HTTPS 网页中包含 HTTP 资源(例如图像、音频、视频等)的情况 ;
在 5.0 以上的设备中 , 默认情况下 不允许 http 和 https 混合加载 , 需要设置允许 http 和 https 混合加载 , 否则部分页面将无法加载 ;
当 mixedContentMode 属性设置为 WebSettings.MIXED_CONTENT_ALWAYS_ALLOW 时,WebView 将允许加载来自不安全来源的混合内容,即使它们来自不安全的 HTTP 网站。
安全提醒 : 这可能会导致安全漏洞,因为混合内容 可以被中间人攻击者用来窃取用户的信息。启用 mixedContentMode 属性可能会危及用户数据的安全性,因此您应该 仅在必要时启用它,并在不需要时禁用它。如果您的网页中包含来自不安全来源的混合内容,建议您尝试将这些资源迁移到 HTTPS 协议上,以避免安全漏洞
// 5.0 以上需要设置允许 http 和 https 混合加载
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
settings.mixedContentMode = WebSettings.MIXED_CONTENT_ALWAYS_ALLOW
} else {
// 5.0 以下不用考虑 http 和 https 混合加载 问题
settings.mixedContentMode = WebSettings.LOAD_NORMAL
}
设置页面自适应
WebSettings.useWideViewPort 属性,用于 控制是否支持 Viewport 元标记的宽度。
Viewport 元标记是指在 HTML 页面中的 <meta> 标签,可以设置网页在移动端设备上的显示方式和缩放比例。
当 useWideViewPort 属性设置为 true 时,WebView 将支持 Viewport 元标记的宽度,并自动调整网页的缩放比例以适应设备的屏幕宽度。
使用场景 : 如果您的 网页在宽屏幕上显示得很好,但在狭窄屏幕上缩放过大或过小,您可以启用此选项。
// 设置页面自适应
// Viewport 元标记是指在 HTML 页面中的 <meta> 标签 , 可以设置网页在移动端设备上的显示方式和缩放比例
// 设置是否支持 Viewport 元标记的宽度
settings.useWideViewPort = true
设置宽视图端口模式
WebSettings.loadWithOverviewMode 属性,用于控制 WebView 是否使用 宽视图端口模式。
在宽视图端口模式下,WebView 会将页面缩小到适应屏幕的宽度。
这意味着用户在浏览网页时无需进行横向滚动,但可能会使网页缩小得过多,影响可读性。
// 设置 WebView 是否使用宽视图端口模式
// 宽视图端口模式下 , WebView 会将页面缩小到适应屏幕的宽度
// 没有经过移动端适配的网页 , 不要启用该设置
settings.loadWithOverviewMode = true
注意,启用 loadWithOverviewMode 属性可能会使网页在狭窄屏幕上显示不正常,因为它会强制缩小网页以适应屏幕宽度。如果网页设计不适用于移动设备,请不要启用该选项 ;
部分代码示例
// 获取并设置 Web 设置
val settings = webview.settings
settings.javaScriptEnabled = true // 支持 JavaScript
// 设置是否启用 DOM 存储
// DOM 存储是一种在 Web 应用程序中存储数据的机制,它使用 JavaScript 对象和属性来存储和检索数据
settings.domStorageEnabled = true
// 设置 WebView 是否启用内置缩放控件 ( 自选 非必要 )
settings.builtInZoomControls = true
// 5.0 以上需要设置允许 http 和 https 混合加载
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
settings.mixedContentMode = WebSettings.MIXED_CONTENT_ALWAYS_ALLOW
} else {
// 5.0 以下不用考虑 http 和 https 混合加载 问题
settings.mixedContentMode = WebSettings.LOAD_NORMAL
}
// 设置页面自适应
// Viewport 元标记是指在 HTML 页面中的 <meta> 标签 , 可以设置网页在移动端设备上的显示方式和缩放比例
// 设置是否支持 Viewport 元标记的宽度
settings.useWideViewPort = true
// 设置 WebView 是否使用宽视图端口模式
// 宽视图端口模式下 , WebView 会将页面缩小到适应屏幕的宽度
// 没有经过移动端适配的网页 , 不要启用该设置
settings.loadWithOverviewMode = true
2、启用调试模式
WebView.setWebContentsDebuggingEnabled 用于在 WebView 中启用调试模式。
调试模式允许您使用 Chrome DevTools 来调试 WebView 中的网页和 JavaScript 代码。
要在 WebView 中启用调试模式,请调用 setWebContentsDebuggingEnabled 方法并将其设置为 true ;
在启用调试模式后,在 Chrome 浏览器中使用 DevTools 调试 WebView 中的网页和 JavaScript 代码。要使用 DevTools,请在 Chrome 地址栏中输入 chrome://inspect,然后按 Enter。在 DevTools 中,您可以查看网络请求、执行 JavaScript 代码、检查元素和样式等。
请注意,调试模式可能会对性能产生一些影响,因此应该仅在需要调试 WebView 中的网页和代码时才启用它。
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
// JavaScript 出错不报异常
try {
// 启用 调试模式
// 由于 WebView#setWebContentsDebuggingEnabled 函数不能直接访问
// 必须使用反射进行访问
val method = Class.forName("android.webkit.WebView")
.getMethod("setWebContentsDebuggingEnabled", java.lang.Boolean.TYPE)
if (method != null) {
method.isAccessible = true
method.invoke(null, true)
}
} catch (e: Exception) {
// JavaScript 出错处理 此处不进行任何操作
}
}
3、设置 WebChromeClient
WebChromeClient 是一个用于 处理 WebView 界面交互事件的类 ;
// WebChromeClient 是一个用于处理 WebView 界面交互事件的类
webview.webChromeClient = object : WebChromeClient() {
// 显示 网页加载 进度条
override fun onProgressChanged(view: WebView, progress: Int) {
val txtProgress = findViewById<TextView>(R.id.textview)
txtProgress.text = String.format(Locale.CHINA, "%d%%", progress)
txtProgress.visibility =
if (progress > 0 && progress < 100) View.VISIBLE else View.GONE
}
// 处理 WebView 对地理位置权限的请求
override fun onGeolocationPermissionsShowPrompt(
origin: String,
callback: GeolocationPermissions.Callback) {
super.onGeolocationPermissionsShowPrompt(origin, callback)
callback.invoke(origin, true, false)
}
}
4、设置 WebViewClient
WebViewClient 是一个用于 处理 WebView 页面加载事件的类 ;
// WebViewClient 是一个用于处理 WebView 页面加载事件的类
webview.webViewClient = object : WebViewClient() {
override fun shouldOverrideUrlLoading(view: WebView, url: String): Boolean {
Log.i("MainActivity", "访问地址 : $url")
// 4.0 之后必须添加该设置
// 只能加载 http:// 和 https:// 页面 , 不能加载其它协议链接
if (url.startsWith("http://") || url.startsWith("https://")) {
view.loadUrl(url)
return true
}
return false
}
// SSL 证书校验出现异常
override fun onReceivedSslError(
view: WebView,
handler: SslErrorHandler,
error: SslError) {
when (error.primaryError) {
SslError.SSL_INVALID, SslError.SSL_UNTRUSTED -> {
handler.proceed()
}
else -> handler.cancel()
}
}
}
5、加载网页
直接调用 WebView#loadUrl 加载网页 ;
// 加载网页
webview.loadUrl("https://www.baidu.com/")
二、Kotlin 代码 ( WebView 设置 )
Kotlin 代码 :
package kim.hsl.webviewdemo
import android.net.http.SslError
import android.os.Build
import android.os.Bundle
import android.view.View
import android.view.Window
import android.view.WindowManager
import android.webkit.*
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import java.util.*
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// 隐藏状态栏和导航栏
requestWindowFeature(Window.FEATURE_NO_TITLE)
// 设置窗口全屏
window.setFlags(
WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN
)
// 加载布局
setContentView(R.layout.activity_main)
// 获取 WebView 组件
val webview = findViewById<WebView>(R.id.webview)
// 获取并设置 Web 设置
val settings = webview.settings
settings.javaScriptEnabled = true // 支持 JavaScript
// 设置是否启用 DOM 存储
// DOM 存储是一种在 Web 应用程序中存储数据的机制,它使用 JavaScript 对象和属性来存储和检索数据
settings.domStorageEnabled = true
// 设置 WebView 是否启用内置缩放控件 ( 自选 非必要 )
settings.builtInZoomControls = true
// 5.0 以上需要设置允许 http 和 https 混合加载
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
settings.mixedContentMode = WebSettings.MIXED_CONTENT_ALWAYS_ALLOW
} else {
// 5.0 以下不用考虑 http 和 https 混合加载 问题
settings.mixedContentMode = WebSettings.LOAD_NORMAL
}
// 设置页面自适应
// Viewport 元标记是指在 HTML 页面中的 <meta> 标签 , 可以设置网页在移动端设备上的显示方式和缩放比例
// 设置是否支持 Viewport 元标记的宽度
settings.useWideViewPort = true
// 设置 WebView 是否使用宽视图端口模式
// 宽视图端口模式下 , WebView 会将页面缩小到适应屏幕的宽度
// 没有经过移动端适配的网页 , 不要启用该设置
settings.loadWithOverviewMode = true
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
// JavaScript 出错不报异常
try {
// 启用 调试模式
// 由于 WebView#setWebContentsDebuggingEnabled 函数不能直接访问
// 必须使用反射进行访问
val method = Class.forName("android.webkit.WebView")
.getMethod("setWebContentsDebuggingEnabled", java.lang.Boolean.TYPE)
if (method != null) {
method.isAccessible = true
method.invoke(null, true)
}
} catch (e: Exception) {
// JavaScript 出错处理 此处不进行任何操作
}
}
// 设置 WebView 是否可以获取焦点 ( 自选 非必要 )
webview.isFocusable = true
// 设置 WebView 是否启用绘图缓存 位图缓存可加速绘图过程 ( 自选 非必要 )
webview.isDrawingCacheEnabled = true
// 设置 WebView 中的滚动条样式 ( 自选 非必要 )
// SCROLLBARS_INSIDE_OVERLAY - 在内容上覆盖滚动条 ( 默认 )
webview.scrollBarStyle = View.SCROLLBARS_INSIDE_OVERLAY
// WebChromeClient 是一个用于处理 WebView 界面交互事件的类
webview.webChromeClient = object : WebChromeClient() {
// 显示 网页加载 进度条
override fun onProgressChanged(view: WebView, progress: Int) {
val txtProgress = findViewById<TextView>(R.id.textview)
txtProgress.text = String.format(Locale.CHINA, "%d%%", progress)
txtProgress.visibility =
if (progress > 0 && progress < 100) View.VISIBLE else View.GONE
}
// 处理 WebView 对地理位置权限的请求
override fun onGeolocationPermissionsShowPrompt(
origin: String,
callback: GeolocationPermissions.Callback) {
super.onGeolocationPermissionsShowPrompt(origin, callback)
callback.invoke(origin, true, false)
}
}
// WebViewClient 是一个用于处理 WebView 页面加载事件的类
webview.webViewClient = object : WebViewClient() {
override fun shouldOverrideUrlLoading(view: WebView, url: String): Boolean {
// 4.0 之后必须添加该设置
// 只能加载 http:// 和 https:// 页面 , 不能加载其它协议链接
if (url.startsWith("http://") || url.startsWith("https://")) {
view.loadUrl(url)
return true
}
return false
}
// SSL 证书校验出现异常
override fun onReceivedSslError(
view: WebView,
handler: SslErrorHandler,
error: SslError) {
when (error.primaryError) {
SslError.SSL_INVALID, SslError.SSL_UNTRUSTED -> {
handler.proceed()
}
else -> handler.cancel()
}
}
}
// 加载网页
webview.loadUrl("https://www.baidu.com/")
}
}
三、全屏设置
在 Activity 加载布局之前 , 设置
// 隐藏状态栏和导航栏
requestWindowFeature(Window.FEATURE_NO_TITLE)
// 设置窗口全屏
window.setFlags(
WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN
)
在 " WebViewDemo\app\src\main\res\values\themes.xml " 中 , 定义如下主题 :
<style name="FullScreenTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:windowFullscreen">true</item>
</style>
然后在 AndroidManifest.xml 清单文件中的 application 节点中 , 设置
<application
android:theme="@style/FullScreenTheme">
</application>
属性 ;
设置上述属性 , 即可实现 Android 全屏设置 ;
四、网络权限设置
在 AndroidManifest.xml 清单文件中的 manifest 根节点中 , 设置
<uses-permission android:name="android.permission.INTERNET" />
子节点 , 即可添加网络权限 ;
五、AndroidManifest.xml 清单文件
AndroidManifest.xml 清单文件 :
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.INTERNET" />
<!-- android:theme="@style/Theme.WebViewDemo" -->
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/FullScreenTheme"
tools:targetApi="31">
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<meta-data
android:name="android.app.lib_name"
android:value="" />
</activity>
</application>
</manifest>