3、WebView基础:Android/iOS WebView基本使用、WebView配置、加载本地与远程H5页面

WebView,说白了就是移动端里的浏览器内核。

你想想看,我们做混合开发,核心就是靠它来承载H5页面。不管是加载远程的运营活动页,还是打包在App里的本地帮助文档,都得通过WebView来渲染。

我个人习惯把WebView比作一个「画框」。原生代码负责搭好画框,H5页面就是画布上的内容。画框的质量,直接决定了展示效果。

3.1 Android WebView 基本使用

Android的WebView使用起来很直接。在布局文件里声明一下,然后在Activity里找到它,加载URL就行了。

// 布局文件 activity_web.xml
<WebView
    android:id="@+id/webview"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

// Java代码
WebView webView = findViewById(R.id.webview);
webView.loadUrl("https://www.example.com");

嗯,这里要注意。Android 9之后,默认是禁止加载HTTP明文流量的。我在项目中遇到过,测试环境用的HTTP地址,结果页面一片空白。查了半天才发现是这个问题。

避坑指南: 我曾经因为没配置网络安全策略,导致线上用户反馈部分页面加载失败。记得在AndroidManifest.xml中配置 android:usesCleartextTraffic="true",或者针对特定域名配置安全策略。

3.2 iOS WebView 基本使用

iOS这边,苹果官方推荐用WKWebView,而不是老旧的UIWebView。WKWebView性能更好,内存占用也更低。

// Swift 代码
import WebKit

class ViewController: UIViewController {
    var webView: WKWebView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        webView = WKWebView(frame: view.bounds)
        view.addSubview(webView)
        
        let url = URL(string: "https://www.example.com")!
        let request = URLRequest(url: url)
        webView.load(request)
    }
}

为什么推荐WKWebView?说白了,UIWebView在加载复杂页面时,内存容易暴涨。我记得有一次测试,同一个页面在UIWebView上占用了200MB内存,换成WKWebView后直接降到了80MB。差距很明显。

3.3 WebView 核心配置

光能加载页面还不够,你得把WebView配置好。不然很多功能都用不了。

配置项 Android iOS 说明
JavaScript支持 getSettings().setJavaScriptEnabled(true) webView.configuration.preferences.javaScriptEnabled = true 必须开启,否则H5交互全废
DOM存储 setDomStorageEnabled(true) 默认开启 H5本地存储需要
文件访问 setAllowFileAccess(true) 默认开启 加载本地文件时必配
缩放控制 setBuiltInZoomControls(true) 通过UIScrollView控制 根据业务需求决定
核心要点: JavaScript支持是混合开发的基石。没有它,原生和H5之间就无法通信。我建议在初始化WebView时就开启,不要等到运行时再动态配置。

3.4 加载本地H5页面

加载本地页面,在混合开发中很常见。比如把帮助文档、协议条款打包进App里。

Android这边,把HTML文件放在 assets 目录下,然后这样加载:

webView.loadUrl("file:///android_asset/help/index.html");

iOS则把文件放在项目Bundle里:

if let path = Bundle.main.path(forResource: "index", ofType: "html", inDirectory: "help") {
    let url = URL(fileURLWithPath: path)
    webView.loadFileURL(url, allowingReadAccessTo: url)
}
个人经验: 加载本地页面时,我习惯把资源文件(CSS、JS、图片)都放在同一个目录下。这样路径管理起来方便,也不容易出现404错误。

3.5 加载远程H5页面

远程页面就简单多了,直接传URL字符串。

// Android
webView.loadUrl("https://api.example.com/activity");

// iOS
let url = URL(string: "https://api.example.com/activity")!
webView.load(URLRequest(url: url))

但这里有个坑。远程页面加载需要网络,如果网络慢或者断网了,页面就会白屏。我曾经在用户反馈里看到过,用户在地铁里打开活动页,结果一直转圈圈。

我的解决方案是:加一个加载进度条,同时设置超时时间。Android用 setWebChromeClient 监听进度,iOS用 WKNavigationDelegatedidStartProvisionalNavigationdidFinish 方法。

3.6 核心知识体系

下面这张图,是我总结的WebView核心知识体系。你一看就明白了。

WebView 核心 基本使用 Android / iOS 初始化 核心配置 JS / DOM / 文件访问 加载本地页面 assets / Bundle 加载远程页面 URL / 网络策略 避坑指南 明文 / 超时 / 内存 WebView 是混合开发的画框,画框搭好了,H5才能尽情发挥

3.7 避坑指南汇总

做WebView开发,坑确实不少。我把常见的几个列出来,你遇到了可以直接翻到这里查。

  • Android 明文流量问题: 记得配置网络安全策略,或者改用HTTPS。
  • iOS WKWebView 白屏: 检查是否在主线程调用UI相关方法。我曾经因为这个排查了一整天。
  • 本地页面资源加载失败: 路径一定要写对。Android用 file:///android_asset/,iOS用 Bundle.main.path
  • JavaScript 交互失效: 确认 setJavaScriptEnabled 已经开启。这个配置默认是关闭的。
  • 内存泄漏: 页面销毁时,记得调用 webView.destroy()(Android)或清理引用(iOS)。
我的习惯: 每次新建WebView页面,我都会先写一个最小可用的Demo。只加载一个简单的HTML,确认基本功能正常后,再逐步添加复杂逻辑。这样出了问题,能快速定位是WebView的问题,还是业务代码的问题。

好了,WebView的基础就这些。说白了,就是初始化、配置、加载三步走。但每一步都有细节,细节决定成败。你动手写一遍,比我讲十遍都管用。

专注资料整理