perf(player): 限制雪碧图与海报预缓存内存并给播放位置缓存加容量上限

雪碧图解码从 2048 降到 1024、缓存从 8 张降到 3 张,避免擦洗预览驻留十几 MB 位图;
相邻集海报预缓存改用 ResizeImage 按 360/720 宽解码,不再缓存整张原图;
播放位置缓存按写入时间淘汰,最多保留 100 条,长会话不再只增不减;
观看记录详情失败日志加 kDebugMode 保护,release 下不再逐条打堆栈。
This commit is contained in:
Vicky authored and trae-solo-agent committed 2026-10-29 11:25:47 +08:00
1 parent fb9001a02d
commit 0f777b19f2
5 files changed
+82 -14

No files matched your search

+27 -5
View File
@@ -61,6 +61,17 @@ const double _playerLoadingSize = 24;
const double _playerLoadingStrokeWidth = 2;
const double _feedRefreshTopGap = 56;
/// 相邻集海报预缓存宽度:列表卡片只有百来 dp,按原图解码会占数 MB。
const int _posterPreviewWidth = 360;
/// 画中画还原封面接近全屏,保留更高分辨率但不必按原图。
const int _posterPipWidth = 720;
/// 预缓存用低分辨率 provider;与 RemoteImage 一样限制解码尺寸,避免整张原图进缓存。
ImageProvider _posterProvider(String url, {required int width}) {
return ResizeImage(NetworkImage(url), width: width, allowUpscaling: false);
}
class PlayerPageHandoff {
PlayerPageHandoff({required this.sourceUserWantsPlay});
@@ -178,7 +189,9 @@ class _PlayerPageState extends State<PlayerPage>
_thumbnailService = PlaybackThumbnailService(
sourceResolver: _resolveThumbnailSource,
);
_spriteAxisService = SpriteThumbnailAxisService(spriteCacheCapacity: 8)
// 雪碧图每张解码后是整块位图,保留 3 部剧足够擦洗回退,8 部在低端机
// 容易把图片缓存顶满甚至触发 OOM。
_spriteAxisService = SpriteThumbnailAxisService(spriteCacheCapacity: 3)
..addListener(_handleSpriteFrameChanged);
WidgetsBinding.instance.addObserver(this);
logic.start(
@@ -507,9 +520,10 @@ class _PlayerPageState extends State<PlayerPage>
final imageUrl = AppConfig.mediaUrl(posterUrl);
if (_precachedPosterUrls.add(imageUrl)) {
unawaited(
precacheImage(NetworkImage(imageUrl), context).catchError((
Object _,
) {
precacheImage(
_posterProvider(imageUrl, width: _posterPreviewWidth),
context,
).catchError((Object _) {
_precachedPosterUrls.remove(imageUrl);
}),
);
@@ -728,7 +742,15 @@ class _PlayerPageState extends State<PlayerPage>
if (logic.pip) {
final poster = logic.trackedEpisode?.posterUrl?.trim();
if (poster != null && poster.isNotEmpty) {
unawaited(precacheImage(NetworkImage(poster), context));
unawaited(
precacheImage(
_posterProvider(
AppConfig.mediaUrl(poster),
width: _posterPipWidth,
),
context,
),
);
}
}
return Stack(