BiliRoamingX项目中的首页推荐广告卡片过滤机制分析
引言
在当今移动应用生态中,广告已经成为平台商业化的重要手段,但过度或不当的广告展示往往会影响用户体验。BiliRoamingX作为B站客户端的增强模块,通过精细化的广告过滤机制,为用户提供了更加纯净的浏览体验。本文将深入分析BiliRoamingX项目中首页推荐广告卡片的过滤机制实现原理。
架构概览
BiliRoamingX的广告过滤系统采用分层架构设计,主要包含以下几个核心组件:
核心过滤机制分析
1. UP主推荐广告过滤
BiliRoamingX通过UpRcmdAdsPatch类实现UP主推荐广告的精准过滤:
@Patch(
name = "Block up recommend ads",
description = "屏蔽UP主推荐广告",
compatiblePackages = [
CompatiblePackage(name = "tv.danmaku.bili"),
CompatiblePackage(name = "tv.danmaku.bilibilihd"),
CompatiblePackage(name = "com.bilibili.app.in")
]
)
object UpRcmdAdsPatch : BytecodePatch() {
override fun execute(context: BytecodeContext) {
context.findClass("Lcom/bapis/bilibili/ad/v1/SourceContentDto;")?.let { c ->
c.mutableClass.methods.find { it.name == "getAdContent" }?.addInstructionsWithLabels(
0, """
invoke-static {}, Lapp/revanced/bilibili/patches/SettingsTransfer;->blockUpRcmdAds()Z
move-result v0
if-eqz v0, :jump
const/4 v0, 0x0
return-object v0
:jump
nop
""".trimIndent()
)
}
}
}
该机制的工作原理如下:
- 字节码注入:在B站客户端的
SourceContentDto.getAdContent()方法中注入过滤逻辑 - 配置检查:通过
SettingsTransfer.blockUpRcmdAds()检查用户配置 - 动态拦截:根据配置决定是否返回空的广告内容
2. 首页推荐内容过滤
首页推荐过滤通过多维度规则实现:
配置参数体系
// 首页推荐过滤设置
@JvmField val FilterHomeRecommend = StringSetSetting(key = "customize_home_recommend")
@JvmField val HomeFilterApplyToVideo = BooleanSetting(key = "home_filter_apply_to_relate")
@JvmField val HomeFilterApplyToPopular = BooleanSetting(key = "home_filter_apply_to_popular")
// 关键词过滤规则
@JvmField val HomeRcmdFilterTitle = StringSetSetting(key = "home_filter_keywords_title")
@JvmField val HomeRcmdFilterTitleRegexMode = BooleanSetting(key = "home_filter_title_regex_mode")
@JvmField val HomeRcmdFilterReason = StringSetSetting(key = "home_filter_keywords_reason")
@JvmField val HomeRcmdFilterUid = StringSetSetting(key = "home_filter_keywords_uid")
@JvmField val HomeRcmdFilterUp = StringSetSetting(key = "home_filter_keywords_up")
// 播放量限制
@JvmField val LowPlayCountLimit = LongSetting(key = "hide_low_play_count_recommend_limit")
@JvmField val ShortDurationLimit = IntSetting(key = "hide_short_duration_recommend_limit")
@JvmField val LongDurationLimit = IntSetting(key = "hide_long_duration_recommend_limit")
过滤逻辑流程
3. Protobuf协议层过滤
BiliRoamingX通过MossHook机制在协议层进行过滤:
object HomeRecent : MossHook<RecentReq, RecentRes>() {
override fun shouldHook(req: GeneratedMessageLite<*, *>): Boolean {
return !Utils.isHd() && req is RecentReq
}
override fun hookAfter(req: RecentReq, reply: RecentRes?, error: MossException?): RecentRes? {
if (reply != null && Settings.BlockHomeRecentUsed())
reply.clearRecentUsed()
return super.hookAfter(req, reply, error)
}
}
技术特点分析
1. 非侵入式设计
BiliRoamingX采用字节码注入技术,无需修改原始应用代码,通过Hook机制实现功能增强:
| 技术手段 | 实现方式 | 优势 |
|---|---|---|
| 字节码注入 | 修改方法指令 | 无需源码,兼容性好 |
| MossHook | 协议层拦截 | 数据层面过滤,效率高 |
| Protobuf处理 | 消息协议解析 | 精准控制数据内容 |
2. 多维度过滤策略
系统支持多种过滤维度,形成完整的过滤体系:
3. 灵活的配置管理
通过SettingsTransfer类实现配置的动态传递:
@Keep
@JvmStatic
fun blockUpRcmdAds(): Boolean {
return Settings.BlockUpRcmdAds()
}
性能优化策略
1. 懒加载机制
private val newPegasusEnabled by lazy {
Utils.getAb("ff_key_use_new_pegasus", false)
}
2. 异步处理
对于资源清理等耗时操作,采用异步执行:
onChange = { value, async ->
if (value) if (async) {
Utils.async { deleteModuleResources() }
} else {
deleteModuleResources()
}
}
3. 条件执行
根据设备类型和版本号进行条件过滤,避免不必要的处理:
override fun shouldHook(req: GeneratedMessageLite<*, *>): Boolean {
return !Utils.isHd() && req is RecentReq
}
实际应用效果
通过上述机制,BiliRoamingX实现了以下效果:
- 广告识别率提升:精准识别UP主推荐广告、原生广告卡片等多种广告形式
- 用户体验优化:减少干扰内容,提升内容浏览效率
- 性能影响最小:采用协议层过滤,对应用性能影响极低
- 配置灵活性:支持用户自定义过滤规则,满足个性化需求
总结
BiliRoamingX项目的首页推荐广告卡片过滤机制体现了现代Android应用增强模块的技术发展趋势:
- 技术先进性:采用字节码注入、协议Hook等前沿技术
- 架构合理性:分层设计,各模块职责清晰
- 用户体验优先:在保证功能的同时最大限度减少性能影响
- 可扩展性强:模块化设计便于后续功能扩展
这种过滤机制不仅为B站用户提供了更加纯净的浏览体验,也为其他类似应用的广告过滤方案提供了有价值的参考。随着移动应用生态的不断发展,这种基于协议层的数据处理技术将在应用增强领域发挥越来越重要的作用。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



