当前位置: 首页 > news >正文

webkitx(Android WebView 最佳实践库)

功能清单

  • WebView 基线设置(JS/存储/深色模式/Cookie)

  • Fragment 容器:BaseWebFragment

  • Activity 容器:BaseWebActivity

  • 导航与资源拦截SafeWebViewClient

    • http/https 内开、非 http(s) 外跳

    • 仅 API 路由注入请求头(Authorization)

    • 离线包路径映射(WebViewAssetLoader

  • UI/权限ChromeClientFragmentChromeClientActivity

    • 进度条、标题、<input type=file>、相机/麦克风权限钩子

  • 登录态TokenSync(推荐:Cookie 同步

  • 离线包热更新OfflineH5Manager(下载/校验/解压/切换/回滚)

  • 下载DownloadHelper + 系统 DownloadManager


1) 目录结构

webkitx/ ├─ build.gradle ├─ proguard-rules.pro ├─ src/main/ │ ├─ AndroidManifest.xml │ ├─ java/com/yourorg/webkitx/ │ │ ├─ WebViewHelper.kt │ │ ├─ TokenSync.kt │ │ ├─ OfflineH5Manager.kt │ │ ├─ SafeWebViewClient.kt │ │ ├─ ChromeClientFragment.kt │ │ ├─ ChromeClientActivity.kt │ │ ├─ BaseWebFragment.kt │ │ ├─ BaseWebActivity.kt │ │ └─ WebKitx.kt // 可选:全局开关 │ ├─ res/layout/fragment_webkitx.xml │ ├─ res/layout/activity_base_webkitx.xml │ ├─ res/xml/network_security_config.xml │ └─ assets/error/net_error.html


2) Gradle & 依赖

根 settings.gradle

include ':app', ':webkitx'

:webkitx/build.gradle

plugins { id 'com.android.library'; id 'org.jetbrains.kotlin.android' } android { namespace 'com.yourorg.webkitx' compileSdk 34 defaultConfig { minSdk 21 consumerProguardFiles 'proguard-rules.pro' } buildFeatures { viewBinding true } } dependencies { implementation "androidx.appcompat:appcompat:1.7.0" implementation "androidx.core:core-ktx:1.13.1" implementation "androidx.activity:activity-ktx:1.9.2" implementation "androidx.fragment:fragment-ktx:1.8.3" implementation "androidx.webkit:webkit:1.11.0" }

在 :app 中加入 implementation project(':webkitx')


3) 必要资源/配置(一键复制)

AndroidManifest.xml

<manifest> <uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> <application android:networkSecurityConfig="@xml/network_security_config" /> </manifest>

res/xml/network_security_config.xml(如需 http 调试域)

<network-security-config> <domain-config cleartextTrafficPermitted="true"> <domain includeSubdomains="true">dev.yourdomain.com</domain> </domain-config> </network-security-config>

res/layout/fragment_webkitx.xml

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/web_root" android:layout_width="match_parent" android:layout_height="match_parent"> <WebView android:id="@+id/web" android:layout_width="match_parent" android:layout_height="match_parent"/> <ProgressBar android:id="@+id/progress" style="?android:attr/progressBarStyleHorizontal" android:layout_width="match_parent" android:layout_height="3dp" android:max="100" android:visibility="gone"/> <FrameLayout android:id="@+id/error_view" android:visibility="gone" android:layout_width="match_parent" android:layout_height="match_parent"/> </FrameLayout>

res/layout/activity_base_webkitx.xml

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/root" android:layout_width="match_parent" android:layout_height="match_parent"> <WebView android:id="@+id/web" android:layout_width="match_parent" android:layout_height="match_parent"/> <ProgressBar android:id="@+id/progress" style="?android:attr/progressBarStyleHorizontal" android:layout_width="match_parent" android:layout_height="3dp" android:max="100" android:visibility="gone"/> </FrameLayout>

assets/error/net_error.html

<!doctype html><meta charset="utf-8"><title>网络异常</title> <style>body{font-family:sans-serif;padding:24px}</style> <h2>网络开小差了</h2><p>请检查网络后重试</p>

proguard-rules.pro

-keep class android.webkit.** { *; } -keepclassmembers class * { @android.webkit.JavascriptInterface <methods>; } -dontwarn org.chromium.**


4) 关键类与职责(已实现)

  • WebViewHelper:初始化 WebSettings、深色模式、Cookie、调试

  • TokenSyncCookie 同步(推荐),附带 token() 占位

  • OfflineH5Manager:离线包下载/校验/解压/切换/回滚;暴露 currentDir() 与 hasBundle()

  • SafeWebViewClient:导航/拦截/SSL/错误;仅 API 路由注入请求头;离线包优先

  • ChromeClientFragment / ChromeClientActivity:进度/标题/文件选择(使用 ActivityResult)

  • DownloadHelper:系统 DownloadManager 下载 + 完成回调

  • BaseWebFragment:组合(Settings + Client + Chrome + Token + Offline)

  • BaseWebActivity:组合(同上)+ DownloadManager 集成

你只需要替换:白名单域名入口 URLTokenSync.token() 获取方式


5) 业务侧如何使用

A) Fragment 版(适合 ViewPager/Tab)

class WebHostActivity : AppCompatActivity(R.layout.activity_host) { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) val frag = BaseWebFragment( startUrl = "https://yourdomain.com/index.html", whiteHosts = setOf("yourdomain.com","api.yourdomain.com","cdn.yourdomain.com"), domainsForCookie = listOf("yourdomain.com","api.yourdomain.com"), offline = OfflineH5Manager(this), enableDebug = BuildConfig.DEBUG ) supportFragmentManager.beginTransaction() .replace(R.id.container, frag) .commit() } override fun onBackPressed() { val f = supportFragmentManager.findFragmentById(R.id.container) as? BaseWebFragment if (f?.canGoBack() == true) f.goBack() else super.onBackPressed() } }

B) Activity 版(简单直接)

class MyWebActivity : BaseWebActivity() { override fun startUrl() = "https://yourdomain.com/index.html" override fun whiteHosts() = setOf("yourdomain.com","api.yourdomain.com","cdn.yourdomain.com") override fun cookieDomains() = listOf("yourdomain.com","api.yourdomain.com") override fun offlineManager() = OfflineH5Manager(this) // 若启用离线包 }


6) 离线包更新(热更流程)

  1. 服务端提供 manifestversionzipUrlsha256

  2. App 下载 zip → offline.installFromZip(zip, version, sha256)

  3. 成功后 OfflineH5Manager.switchTo(version)(封装里已做)

  4. WebView 入口统一:

    • 在线:https://yourdomain.com/index.html

    • 离线:https://appassets.androidplatform.net/dynamic/index.html

  5. 如需回滚:offline.rollback()

BaseWebFragment/Activity 已根据 offline.hasBundle() 自动选择入口。


7) Token 注入策略(优先级)

  1. Cookie 同步(推荐)
    TokenSync.syncCookie(web, listOf("yourdomain.com","api.yourdomain.com"))
    后端从 Cookie 读取 AUTH_TOKEN

  2. 请求头注入(仅 API 路由)
    SafeWebViewClient.extraHeadersProvider = { mapOf("Authorization" to "Bearer ${TokenSync.token()}") }
    并通过 isApiPath(uri) 严格限制在 /api/**不要给静态资源加头

  3. JS 注入(备选)
    web.evaluateJavascript("window.__TOKEN__='${TokenSync.token()}';", null)


8) 下载(DownloadManager)

  • WebView 内部下载链接 → 交给系统 DownloadManager

  • 模块中已在 BaseWebActivity 里注册:

    • setDownloadListener{ url, ua, cd, mime, _ -> DownloadHelper.enqueue(...) }

    • 完成广播 DownloadHelper.registerCompletionReceiver(...)

Android Q+ 下载到公有 Downloads 目录无需手动存储权限;如需通知权限(Android 13+),在 App 动态申请 POST_NOTIFICATIONS


9) 扩展与开关

  • 域名白名单whiteHosts()

  • Cookie 同步域cookieDomains()

  • 仅 API 路由:在 SafeWebViewClient.isApiPath 中自定义

  • 调试WebViewHelper.init(web, enableDebug = BuildConfig.DEBUG)

  • 错误页error_view 自定义 UI;或加载 assets/error/net_error.html


10) 上线安全核查清单

  • onReceivedSslError() 一律 cancel(禁止放行自签证书)

  • 仅对 API 路由加请求头;禁止给静态资源加头

  • Scheme 外跳(weixin://alipays://tel:)留在白名单内显式处理

  • 仅在可信域注入 @JavascriptInterface(如后续要加 Bridge)

  • 生产关闭不必要的 mixedContent;能 https 就 https


11) 最少需要你改的 3 处

  1. 域名yourdomain.comwhiteHosts & cookieDomains

  2. 入口 URLstartUrl

  3. Token 获取:实现 TokenSync.token()

http://www.dtcms.com/a/557488.html

相关文章:

  • 调查网站做调查不容易过横栏建设网站
  • 勐海县住房和城乡建设局网站南昌做网站费用
  • 感知上下文并可解释地预测合成致死药物靶点的大语言模型研究
  • AI研究-117 特斯拉 FSD 视觉解析:多摄像头 - 3D占用网络 - 车机渲染,盲区与低速复杂路况安全指南
  • 二级域名可以做网站吗免费个人博客网站模板下载
  • 复原大唐3d项目测试版
  • 2024年MySQL 下载、安装及启动停止教程(非常
  • 兰州百度网站建设百度网站关键词优化在哪里做
  • Redis——Windows安装
  • 微信网站开发视频教程免费的黄金软件
  • 【高级机器学习】0. Machine Learning 介绍
  • 昆明城乡和住房建设局网站网站做5级分销合法吗
  • .NETCore、.NET 7 和 RabbitMQ 的发布-订阅模式
  • Crashpad 在windows下编译和使用指南
  • 基于SpringBoot+Vue的农产品销售系统【协同过滤推荐算法+可视化统计】
  • 基于flet的一款windows桌面应用,实现了浏览图片、音乐、小说、各种资源的功能
  • 【开题答辩过程】以《基于微信小程序的线上讲座管理系统》为例,不会开题答辩的可以进来看看
  • 怎么做好网站建设新手怎么开传媒公司
  • 2025年8月AGI月评|AI开源项目全解析:从智能体到3D世界,技术边界再突破
  • CSP-J/S 2025 游记
  • 深入洞察:业务流程从概念到实践
  • realloc用法
  • 智慧团建网站登录电脑版装饰工程有限公司的经营范围
  • STM32学习(MCU控制)(SPI and Flash 存储)
  • 网站推广有哪些方案pr免费模板网站
  • 轻量级HTTPSocks代理GOST: Linux编译安装
  • 有没有教做健身餐的网站wordpress菜单跳转
  • 以小白视角尝试 WPF / WinUI3 / MAUI / MAUI Blazor 构建 Windows 桌面程序
  • 网络原理-进阶
  • 百度搜索什么关键词能搜到网站大学生创新创业网站建设内容