携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第二十天,点击查看活动详情
重学Android之----Webview的常用方法
前言
Webview是Android中自带的一个控件,能够提供开发开发者显示网页,Webview内部实现是采用渲染引擎(WebKit)来展示view的内容,提供网页前进后退、网页放大、缩小、搜索等功能
Webview的基本使用
显示百度页面
我们使用Webview来显示一个百度页面
- 添加Webview到xml:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<WebView
android:id="@+id/webview"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
- 我们在是Activity中使Webview显示百度页面:
package com.wechat.webview
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.webkit.WebView
import android.webkit.WebViewClient
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
initWebView()
}
fun initWebView(){
//绑定控件
val webview = findViewById<WebView>(R.id.webview)
//设置webvie回调
webview.webViewClient = object :WebViewClient(){
//监听错误回调信息
override fun onReceivedError(
view: WebView?,
errorCode: Int,
description: String?,
failingUrl: String?
) {
Log.e("webvieweeeeee", "onReceivedError: $errorCode ----- $description", )
}
}
//加载百度页面
webview.loadUrl("https://www.baidu.com/")
}
}
- 别忘了添加网络权限:
<uses-permission android:name="android.permission.INTERNET" />
我们运行一下,发现出现这样的错误:
错误信息:
2022-08-30 17:20:39.985 28433-28433/com.wechat.webview E/webvieweeeeee: onReceivedError: -1 ----- net::ERR_CLEARTEXT_NOT_PERMITTED
但是我们明明已经加了网络权限?
从Android 9.0(API级别28)开始,默认情况下限制了明文流量的网络请求,对未加密流量不再信任,直接放弃请求,因此http的url均无法在webview中加载。
- 解决方案一:
在AndroidManifest.xml文件中的Application标签添加android:usesCleartextTraffic="true"
<application
...
//添加代码
android:usesCleartextTraffic="true"
...
>
- 解决方案二:
在AndroidManifest.xml文件中的Application标签添加android:networkSecurityConfig="@xml/network_security_config"
<application
...
//添加代码
android:networkSecurityConfig="@xml/network_security_config"
...
>
network_security_config:
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config cleartextTrafficPermitted="true" />
</network-security-config>
我们在运行一下就可以看到百度了:
Webview常用方法
- 生命周期
//激活WebView为活跃状态,能正常执行网页的响应
webView.onResume()
//当页面被失去焦点被切换到后台不可见状态,需要执行onPause
webView.onPause()
//当应用程序(存在webview)被切换到后台时,这个方法不仅仅针对当前的webview而是全局的全应用程序的webview
webView.pauseTimers()
//恢复pauseTimers状态
webView.resumeTimers()
//销毁Webview
webView.destroy();
- 前进 / 后退网页
//是否可以后退
Webview.canGoBack()
//后退网页
Webview.goBack()
//是否可以前进
Webview.canGoForward()
//前进网页
Webview.goForward()
//以当前的index为起始点前进或者后退到历史记录中指定的steps
//如果steps为负数则为后退,正数则为前进
Webview.goBackOrForward(intsteps)
- 清理缓存数据
//清除网页访问留下的缓存
//由于内核缓存是全局的因此这个方法不仅仅针对webview而是针对整个应用程序.
Webview.clearCache(true);
//清除当前webview访问的历史记录
//只会webview访问历史记录里的所有记录除了当前访问记录
Webview.clearHistory();
//这个api仅仅清除自动完成填充的表单数据,并不会清除WebView存储到本地的数据
Webview.clearFormData();
- WebSetting
WebSetting是对WebView进行设置
//获取webview的settings
val settings = webview.settings
//获取Ua
settings.userAgentString
//支持js
settings.javaScriptEnabled = true
//将图片调整到适合webview的大小
settings.useWideViewPort = true
// 缩放至屏幕的大小
settings.loadWithOverviewMode = true
//将图片调整到适合webview的大小
settings.setSupportZoom(true)
//设置内置的缩放控件。若为false,则该WebView不可缩放
settings.builtInZoomControls = true
//隐藏原生的缩放控件
settings.displayZoomControls = false
//关闭webview中缓存
settings.cacheMode = WebSettings.LOAD_DEFAULT
//设置可以访问文件
settings.allowFileAccess = true
//支持通过JS打开新窗口
settings.javaScriptCanOpenWindowsAutomatically = true
//支持自动加载图片
settings.loadsImagesAutomatically = true
//设置编码格式
settings.defaultTextEncodingName = "utf-8"
- WebViewClient
WebViewClient是Webview进行请求后的一些时间回调和处理
-
shouldOverrideUrlLoading() 当即将在当前 WebView 中加载 URL 时,让宿主应用程序有机会进行控制。如果未提供 WebViewClient,默认情况下 WebView 将要求 Activity Manager 为 URL 选择正确的处理程序。如果提供了 WebViewClient,返回
true会导致当前 WebView 中止加载 URL,而返回false会导致 WebView 像往常一样继续加载 URL。 -
shouldInterceptRequest
将资源请求通知宿主应用程序并允许应用程序返回数据。如果返回值为null,则 WebView 将照常继续加载资源。否则,将使用返回响应和数据。
该回调被各种 URL 方案调用(例如,http(s):、data:、file:等),而不仅仅是那些通过网络发送请求的方案。这不适用于javascript:URL、 URL或blob:通过 URL 访问的资产。 file:///android_asset/``file:///android_res/
在重定向的情况下,仅对初始资源 URL 调用,而不是任何后续重定向 URL。
- onPageStarted
通知主机应用程序页面已开始加载。每次加载主框架时都会调用一次此方法,因此具有 iframe 或框架集的页面将为主框架调用一次 onPageStarted。这也意味着当嵌入框架的内容发生变化时不会调用 onPageStarted,即单击目标是 iframe 的链接,也不会调用片段导航
- onPageFinished
通知主机应用程序页面已完成加载。此方法仅对主机调用。接收onPageFinished()回调并不能保证 WebView 绘制的下一帧将反映此时 DOM 的状态。为了通知当前 DOM 状态已准备好呈现,请求一个可视状态回调WebView#postVisualStateCallback并等待触发提供的回调。
- onReceivedError
向主机应用程序报告 Web 资源加载错误。这些错误通常表示无法连接到服务器。请注意,与不推荐使用的回调版本不同,新版本将针对任何资源(iframe、图像等)调用,而不仅仅是主页。因此,建议在此回调中执行所需的最少工作
总结
Webview的基本使用和常用方法就在这些,我们在日常开发中,Webview的使用场景并不多,但是有些情况是使用Webview(纯web开发app,获取cookie等)的,那么我们就需要了解Webview的一些方法来实现特定的需求