文章目录
博客代码 :
设置 WebSettings 前 , 要先获取 WebSettings 实例对象 , 调用 WebView#getSettings 函数 , 可以获取该 WebSettings 实例对象 ;
// 获取并设置 Web 设置
val settings = webview.settings
设置 WebView 是否 启用 JavaScript 代码执行 ;
该选项必须启用 , 否则大部分网页都无法使用 ;
settings.javaScriptEnabled = true // 支持 JavaScript
DOM 存储是一种 在 Web 应用程序中存储数据的机制,它使用 JavaScript 对象和属性来存储和检索数据 ;
启用 DOM 存储后,Web 应用程序可以 在客户端上存储和检索数据,而 无需向服务器发出请求。这可以 减少网络流量和提高性能,但可能会占用更多的设备存储空间。
如果 Web 应用程序需要在客户端上存储数据以提高性能,那么启用 DOM 存储是一个不错的选择。
启用 DOM 存储可能会占用更多的设备存储空间,因此您应该在必要时使用它,并在不需要时禁用它。
// 设置是否启用 DOM 存储
// DOM 存储是一种在 Web 应用程序中存储数据的机制,它使用 JavaScript 对象和属性来存储和检索数据
settings.domStorageEnabled = true
设置 WebView 是否 启用内置缩放控件 ;
当 builtInZoomControls 属性设置为 true 时,WebView 将在屏幕上显示一个简单的缩放控件,用户可以使用它来放大或缩小网页。
通过双指捏合手势也可以进行缩放。启用内置缩放控件可以提高用户的体验,使其更容易在移动设备上浏览网页。
如果网页已经自适应了移动设备的屏幕大小并且用户可以通过双指捏合手势来缩放网页,那么不需要启用此选项。
// 设置 WebView 是否启用内置缩放控件 ( 自选 非必要 )
settings.builtInZoomControls = true
当使用双指捏合缩放时 , 右下角就会出现下面的缩放控件 ;

设置 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
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 出错处理 此处不进行任何操作
}
}
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)
}
}
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()
}
}
}
直接调用 WebView#loadUrl 加载网页 ;
// 加载网页
webview.loadUrl("https://www.baidu.com/")
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 清单文件 :
<?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>
我有一个Ruby程序,它使用rubyzip压缩XML文件的目录树。gem。我的问题是文件开始变得很重,我想提高压缩级别,因为压缩时间不是问题。我在rubyzipdocumentation中找不到一种为创建的ZIP文件指定压缩级别的方法。有人知道如何更改此设置吗?是否有另一个允许指定压缩级别的Ruby库? 最佳答案 这是我通过查看rubyzip内部创建的代码。level=Zlib::BEST_COMPRESSIONZip::ZipOutputStream.open(zip_file)do|zip|Dir.glob("**/*")d
我有一个模型:classItem项目有一个属性“商店”基于存储的值,我希望Item对象对特定方法具有不同的行为。Rails中是否有针对此的通用设计模式?如果方法中没有大的if-else语句,这是如何干净利落地完成的? 最佳答案 通常通过Single-TableInheritance. 关于ruby-on-rails-Rails-子类化模型的设计模式是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.co
我在使用omniauth/openid时遇到了一些麻烦。在尝试进行身份验证时,我在日志中发现了这一点:OpenID::FetchingError:Errorfetchinghttps://www.google.com/accounts/o8/.well-known/host-meta?hd=profiles.google.com%2Fmy_username:undefinedmethod`io'fornil:NilClass重要的是undefinedmethodio'fornil:NilClass来自openid/fetchers.rb,在下面的代码片段中:moduleNetclass
对于具有离线功能的智能手机应用程序,我正在为Xml文件创建单向文本同步。我希望我的服务器将增量/差异(例如GNU差异补丁)发送到目标设备。这是计划:Time=0Server:hasversion_1ofXmlfile(~800kiB)Client:hasversion_1ofXmlfile(~800kiB)Time=1Server:hasversion_1andversion_2ofXmlfile(each~800kiB)computesdeltaoftheseversions(=patch)(~10kiB)sendspatchtoClient(~10kiBtransferred)Cl
我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i
我构建了两个需要相互通信和发送文件的Rails应用程序。例如,一个Rails应用程序会发送请求以查看其他应用程序数据库中的表。然后另一个应用程序将呈现该表的json并将其发回。我还希望一个应用程序将存储在其公共(public)目录中的文本文件发送到另一个应用程序的公共(public)目录。我从来没有做过这样的事情,所以我什至不知道从哪里开始。任何帮助,将不胜感激。谢谢! 最佳答案 无论Rails是什么,几乎所有Web应用程序都有您的要求,大多数现代Web应用程序都需要相互通信。但是有一个小小的理解需要你坚持下去,网站不应直接访问彼此
我尝试运行2.x应用程序。我使用rvm并为此应用程序设置其他版本的ruby:$rvmuseree-1.8.7-head我尝试运行服务器,然后出现很多错误:$script/serverNOTE:Gem.source_indexisdeprecated,useSpecification.Itwillberemovedonorafter2011-11-01.Gem.source_indexcalledfrom/Users/serg/rails_projects_terminal/work_proj/spohelp/config/../vendor/rails/railties/lib/r
鉴于我有以下迁移:Sequel.migrationdoupdoalter_table:usersdoadd_column:is_admin,:default=>falseend#SequelrunsaDESCRIBEtablestatement,whenthemodelisloaded.#Atthispoint,itdoesnotknowthatusershaveais_adminflag.#Soitfails.@user=User.find(:email=>"admin@fancy-startup.example")@user.is_admin=true@user.save!ende
我正在查看instance_variable_set的文档并看到给出的示例代码是这样做的:obj.instance_variable_set(:@instnc_var,"valuefortheinstancevariable")然后允许您在类的任何实例方法中以@instnc_var的形式访问该变量。我想知道为什么在@instnc_var之前需要一个冒号:。冒号有什么作用? 最佳答案 我的第一直觉是告诉你不要使用instance_variable_set除非你真的知道你用它做什么。它本质上是一种元编程工具或绕过实例变量可见性的黑客攻击
刚入门rails,开始慢慢理解。有人可以解释或给我一些关于在application_controller中编码的好处或时间和原因的想法吗?有哪些用例。您如何为Rails应用程序使用应用程序Controller?我不想在那里放太多代码,因为据我了解,每个请求都会调用此Controller。这是真的? 最佳答案 ApplicationController实际上是您应用程序中的每个其他Controller都将从中继承的类(尽管这不是强制性的)。我同意不要用太多代码弄乱它并保持干净整洁的态度,尽管在某些情况下ApplicationContr