重学Android之----Webview的常用方法

724 阅读5分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第二十天,点击查看活动详情

重学Android之----Webview的常用方法

前言

Webview是Android中自带的一个控件,能够提供开发开发者显示网页,Webview内部实现是采用渲染引擎(WebKit)来展示view的内容,提供网页前进后退、网页放大、缩小、搜索等功能

Webview的基本使用

显示百度页面

我们使用Webview来显示一个百度页面

  1. 添加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>
  1. 我们在是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/")

    }
}
  1. 别忘了添加网络权限:
<uses-permission android:name="android.permission.INTERNET" />

我们运行一下,发现出现这样的错误: Screenshot_20220830_172048_com.wechat.webview.jpg

错误信息:

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>

我们在运行一下就可以看到百度了:

Screenshot_20220830_171628_com.wechat.webview.jpg

Webview常用方法

  1. 生命周期
//激活WebView为活跃状态,能正常执行网页的响应
webView.onResume()

//当页面被失去焦点被切换到后台不可见状态,需要执行onPause
webView.onPause()

//当应用程序(存在webview)被切换到后台时,这个方法不仅仅针对当前的webview而是全局的全应用程序的webview
webView.pauseTimers()

//恢复pauseTimers状态
webView.resumeTimers()

//销毁Webview
webView.destroy();
  1. 前进 / 后退网页
//是否可以后退
Webview.canGoBack() 

//后退网页
Webview.goBack()

//是否可以前进                     
Webview.canGoForward()

//前进网页
Webview.goForward()

//以当前的index为起始点前进或者后退到历史记录中指定的steps
//如果steps为负数则为后退,正数则为前进
Webview.goBackOrForward(intsteps) 

  1. 清理缓存数据
//清除网页访问留下的缓存
//由于内核缓存是全局的因此这个方法不仅仅针对webview而是针对整个应用程序.
Webview.clearCache(true);

//清除当前webview访问的历史记录
//只会webview访问历史记录里的所有记录除了当前访问记录
Webview.clearHistory();

//这个api仅仅清除自动完成填充的表单数据,并不会清除WebView存储到本地的数据
Webview.clearFormData();
  1. 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"

  1. 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的一些方法来实现特定的需求