ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

web-to-app Hosts 广告拦截深度解析:过滤列表订阅、美化过滤与 APK 内编译规则

web-to-app Hosts 广告拦截深度解析:过滤列表订阅、美化过滤与 APK 内编译规则 web-to-app Hosts 广告拦截深度解析过滤列表订阅、美化过滤与 APK 内编译规则【免费下载链接】web-to-appThe most full featured web-to-app toolkit on Android, a complete APK workshop that runs entirely on your phone项目地址: https://gitcode.com/GitHub_Trending/web/web-to-app本篇围绕 web-to-app 的 Hosts Ad Blocking 功能展开它会讲清这个基于 hosts 规则 美化cosmetic过滤的拦截器如何管理 20 个社区过滤列表、如何解析与匹配 ABP/hosts 规则、如何按页面注入隐藏 CSS 与反反拦截脚本以及同一套编译规则如何同时服务应用内预览与导出 APK。读完之后你既能掌握界面层面的订阅管理操作也能从源码级别理解规则从下载、解析、索引到注入的完整链路。功能定位与入口Hosts Ad Blocking 是一个独立的过滤规则管理中心入口在应用主界面的⋮ → Hosts Ad Blocking对应文档 主界面 More。它的职责有两层规则库管理下载、导入、启用/禁用、删除过滤列表预设 20 个 用户自定义源并提供规则搜索与一键清空。拦截引擎供给宿主级阻断hosts 规则、网络级过滤ABP 语法、元素级隐藏cosmetic 过滤分别服务于应用内 WebView 预览和导出 APK 的运行期。界面实现在 HostsAdBlockScreen.kt引擎核心是单例 AdBlocker.kt约 2800 行磁盘缓存由 AdBlockFilterCache.kt 承担。界面功能全览与界面逐项对应各功能在源码中的落点如下界面功能说明源码依据活跃规则数顶部展示当前加载的阻断规则总量getHostsFileRuleCount/getImportedHostsRuleCountHostsAdBlockScreen.kt#L119-L127Sources 管理预设列表逐个下载支持从文件导入importHostsFromFile系统文件选择器、从 URL 导入importHostsFromUrl、删除源同屏文件内filePickerLauncher/importSource回调自定义源卡片文件导入 / 自定义 URL 的源会获得显示名优先取 ContentResolver 文件名或列表头! Title:渲染为独立卡片支持启用/禁用/删除getCustomHostsSources()AdBlocker.kt#L1507-L1519内置列表20 个社区过滤列表见下节getPopularHostsSources()AdBlocker.kt#L219-L324Search按名称/描述/URL 过滤预设与自定义源另有 All / Downloaded / Not downloaded 三档过滤器HostsFilter枚举与filteredSourcesHostsAdBlockScreen.kt#L86-L190Clear清空全部已加载规则带确认对话框WtaAlertDialog屏内showClearDialog状态下载过程不是“点了就等”importHostsFromUrl以 8KB 缓冲分块读取进度回调被节流到每秒最多 6 次并始终发出最后一次界面用LinearProgressIndicator展示字节数、速度与 ETAAdBlocker.kt#L2200-L2302、DownloadProgress。内置列表源20 个社区过滤列表getPopularHostsSources()硬编码了 20 个预设源覆盖 EasyList、uBlock Origin、AdGuard、AdAway 四大体系及 8 个语言/地区专属列表名称说明EasyList国际主广告过滤列表AdBlock 社区维护EasyPrivacy追踪器与分析阻断uBlock FiltersuBlock Origin 默认过滤面向现代广告技术uBlock PrivacyuBlock Origin 隐私专用过滤AdGuard Base广覆盖的国际广告过滤AdGuard Tracking Protection分析与遥测阻断AdGuard AnnoyancesCookie 提示、订阅弹窗等打扰StevenBlack Hosts经典 hosts 文件源AdAway DefaultAdAway 默认 hosts 列表Peter Lowes List广告/追踪服务器黑名单1Hosts Lite轻量 hosts 列表EasyList Germany德/奥/瑞域名Liste FR (France)法国域名EasyList Dutch荷/比域名EasyList Italy意大利域名EasyList Spanish西语/拉美域名EasyList Portuguese葡/巴域名AdGuard Japanese日语站点与日本广告网络EasyList China中文站点AdGuard DNS FilterDNS 层面的过滤规则每个源携带name/url/description三元组HostsSource部分描述通过 Strings.kt 做多语言化——getPopularHostsSources()因此可动态取文案而旧的POPULAR_HOSTS_SOURCES常量已被标记Deprecated。规则导入hosts 与 ABP 双格式自动识别导入入口是parseFilterContent()AdBlocker.kt#L2304-L2343。它先扫描前 20 行判断内容属于 ABP 格式出现[Adblock...]、!、||、、##、##等特征还是传统 hosts 格式hosts 格式走parseHostLine()兼容0.0.0.0 example.com、127.0.0.1 example.com、::1、||example.com^以及裸域名行随后经isValidHost()过滤 IP 地址、localhost系主机名、超长或含..的非法域名。ABP 格式逐行交给parseAndAddRule()按分隔符优先级#$#、#$#、#?#、#?#、##、##分派到四类解析器网络规则||host/path$script,third-party、例外→parseNetworkFilter()选择器隐藏##.ad-banner、##div[id^taboola-]→parseCosmeticFilter()AdGuard CSS 注入domain#$#selector { ... }→parseCssInjection()脚本规则##js(...)、#%#//scriptlet(...)→parseScriptletRule()注意它们必须优先于选择器解析处理否则会把js(...)负载当成非法 CSS 污染隐藏批次。解析过程中还有一个工程细节捕获OutOfMemoryError后触发 GC 并保留已解析的部分规则集低内存设备上导入超大列表的保底策略源码注释明确提到 AdGuard Base 单文件约 6.4MB。ABP 模式到正则的翻译与惰性编译translateAbpPattern()AdBlocker.kt#L2572-L2608完成 ABP 通配到 Java 正则源串的翻译^先转为字符类[^\\w%.\\-]必须先于锚点转换否则会破坏||host/path规则中插入的[^/]类再处理||子域前缀匹配、|首/尾锚点、*通配/regex/原样保留。MAX_ABP_PATTERN_LEN 1024上限与连续星号检测用于防御恶意/畸形规则。更关键的是两段式编译导入时只做便宜的字符串翻译昂贵的Regex编译延迟到规则首次命中时执行NetworkFilter.regex()。源码注释给出了理由一个 10 万条规则的列表若在导入期全部编译会驻留约 100MB 的 Pattern 对象足以让 256MB 堆的设备 OOM——而导出 APK 时还会构建第二台引擎压力加倍。匹配结果另有 2048 条上限的 LRU 缓存blockResultCache缓存键包含 URL、页面主机、资源类型与三态标记保证例外规则...$domain...跨页面结果正确。匹配判定链路shouldBlock()AdBlocker.kt#L872-L916的判定顺序命中SAFELIST_HOSTS翻译、CDN、登录、支付、reCAPTCHA 等关键域白名单直接放行DOCUMENT 与 FONT 永不拦截first-party 样式表也不拦截命中ESSENTIAL_RESOURCE_REGEXjquery/react/api/login/checkout 等路径特征放行主机精确命中exactHosts/hostsFileHosts后再查例外规则决定是否放行依次查网络例外 → 网络阻断带 anchor 域倒排索引加速anchorDomainIndex 未锚定剩余索引兜底启发式first-party 请求若路径命中FIRST_PARTY_AD_PATH_REGEX/ads/、/doubleclick/、/ad-slot/等按 script/xhr/subdocument 类型阻断。资源类型可由调用方传入也可从请求头推断inferResourceTypeFromRequest()依据Accept头与扩展名这使拦截器既能服务shouldBlock(url, pageHost, resourceType, isThirdParty)也能直接消费WebResourceRequest。美化过滤Cosmetic Filtering除 hosts 级阻断外引擎内置一套 MutationObserver 驱动的元素隐藏机制buildCosmeticRules()。每个页面的隐藏规则被按50 个选择器一批切分生成 CSSdisplay:none等六属性全!important批次以getCosmeticHideBatches()暴露给页面内 DOM 观察脚本按批查询——这样单个非法选择器只会让它所在批次失效不会连坐整条逗号拼接链对应源码注释中的 issue #823 防护。CosmeticFilter数据结构AdBlocker.kt#L86-L102支持四种形态普通选择器##.ad-banner、###ad_top等引擎还内置一批兜底选择器ins.adsbygoogle、[id^div-gpt-ad]、[class*taboola]等:style(...)重载uBO 语法只重排不隐藏作为独立 CSS 规则输出避免混入隐藏批次把“只想改颜色”的元素藏掉#$#完整 CSS 注入AdGuard 语法作为整条规则直接拼接过程式伪类:has-text()/:upward()/:remove()编译为t:text、u:arg、r操作码序列由页面侧 JS 逐条求值getCosmeticProceduralRulesJs()嵌套伪类或无法识别的 uBO 专属伪类:xpath、:watch-attr等 21 种在解析期直接丢弃防止非法 CSS 污染批次。例外规则##按页面主机域匹配后从隐藏集合中按选择器精确抵消。所有 per-host 产物CSS、反反拦截脚本、隐藏批次、过程式 JS经cosmeticCache128 条上限 版本号失效按主机记忆化规则变更统一走invalidateCache()/bumpCosmeticVersion()使缓存失效。反反拦截Anti-Adblock脚本buildAntiAdblockScript()AdBlocker.kt#L1139-L1166把页面命中的 scriptlet 与一段通用反检测脚本打包注入通用部分UNIVERSAL_ANTI_ADBLOCK_SCRIPTAdBlocker.kt#L2627 起覆盖五种常见检测手法创建隐形诱饵广告元素、置位window.fuckAdBlock/google_ad_status等检测变量、用 MutationObserver 拆除 fixed/sticky 拦截墙并恢复被锁的滚动、代理getComputedStyle让诱饵元素“看起来可见”、拦截指向检测信标 URL 的 fetch/XHR 并伪造 200 响应。scriptlet 支持abort-on-property-read/write、abort-current-inline-script、set-constant、remove-attr、remove-class、nano-setInterval/Timeout-booster、prevent-addEventListener、prevent-fetch、prevent-xhr等十余种每种都内联生成独立 JSgenerateScriptlet()。订阅生命周期注册表、缓存与自动刷新过滤源的状态落盘在filesDir下的两份文件adblock_hosts_sources.txtregistry v3每行URL \t 规则数 \t 启用标志 \t 显示名 \t 上次刷新时间戳 \t 刷新间隔saveSourcesRegistry()v2/v3 新增列均为可选向前兼容adblock_hosts.txt与编译态缓存AdBlockFilterCache.saveCompiledState重启后loadHostsRules()优先从编译态恢复避免重新解析全部列表AdBlocker.kt#L2411-L2433仅配置 UI 需要的轻量元数据路径则走hydrateSourcesMetadata()不加载完整过滤库防止多张大列表耗尽堆内存。自动刷新策略AdBlocker.kt#L128-L145刷新间隔取自列表头的! Expires: N days|hours并被夹在 6 小时至 14 天之间防止恶意或拼错的头造成热循环无头则默认 24 小时kickSourceRefresh()在后台 IO 协程中刷新所有到期源本应用订阅 Hosts Blocking 已启用源的并集失败源进入 1 小时内存退避失败时保留旧内容fail-soft内容变化后在引擎互斥锁内rebuildEngine()重建“与上次prepareRuntimeFilters完全相同的规则宇宙”因此刷新不会与并发准备竞争下载参数15s 连接超时、30s 读取超时、User-Agent: WebToApp/1.0内容同时写入 24 小时 URL 缓存AdBlockFilterCache。预览与导出同一规则集的两种消费方式文档 Privacy Hardening 将广告拦截列为主题能力之一按应用的开关与订阅在 Ad Blocking 配置卡Edit Common Config → Privacy中选定——选择器同时提供内置列表与用户导入的自定义源。预览侧WebViewActivity在页面导航前调用prepareRuntimeFilters(enabled, customRules, subscriptionUrls)WebViewActivity.kt#L1504-L1561装载规则WebViewManager.kt 在请求拦截钩子中对每个子请求执行adBlocker.shouldBlock(url, pageHost, resType, isThirdParty)L2012命中后按资源类型返回伪造响应脚本返回/* blocked */、图片返回 1x1 透明 GIF、XHR 返回{}页面注入阶段则拼接getCosmeticFilterCss(pageHost)L2361与getAntiAdblockScript(pageHost)L5278-L5302。导出侧构建 APK 时config.adBlock.enabled为真则新建一台独立的AdBlocker实例按该应用的订阅列表执行compileRulesText()ApkBuilder.kt#L1576-L1594把全部规则编译回 ABP 文本||host^ 原始 raw 规则行后压缩写入assets/wta_adblock_compiled.txt随包分发给导出应用的运行期引擎。这也解释了惰性编译注释中“导出会构建第二台引擎”的压力来源。测试覆盖该功能的单元测试集中在 app/src/test/java/com/webtoapp/core/adblock/AdBlockerTest.kt — 规则解析与匹配主逻辑AdBlockLazyRegexTest.kt — 验证正则延迟编译行为AdBlockSubscriptionRefreshTest.kt — 订阅刷新间隔、退避与重建AdBlockerCustomSourcesTest.kt — 自定义源显示名与卡片元数据AdBlockerHostRuntimeTest.kt — 运行期主机规则装载。小结Hosts Ad Blocking 的设计可以用一句话概括界面是订阅管理器AdBlocker是规则编译器WebView 注入与 APK 导出只是规则集的两个出口。它通过 hosts/ABP 双格式自动识别、惰性正则编译、anchor 域倒排索引与 LRU 结果缓存把百万级请求的判定成本压到可接受区间又用注册表版本化、! Expires:夹取、失败退避保证订阅在低内存 Android 设备上的长期可用性。若你为自己的 web 应用开启广告拦截只需在 Privacy → Ad Blocking 中勾选所需订阅预览即时生效导出时规则即被编译进 APK无需额外配置。【免费下载链接】web-to-appThe most full featured web-to-app toolkit on Android, a complete APK workshop that runs entirely on your phone项目地址: https://gitcode.com/GitHub_Trending/web/web-to-app创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表