From 12dc36cecbbf61016fc34827e878f3ff9426e3d6 Mon Sep 17 00:00:00 2001 From: cnoim Date: Mon, 27 Jul 2026 16:58:56 +0800 Subject: [PATCH 1/7] =?UTF-8?q?fix(status=5Fbar):=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E7=8A=B6=E6=80=81=E6=A0=8F=E7=82=B9=E5=87=BB=E4=BA=8B=E4=BB=B6?= =?UTF-8?q?=E5=8F=AF=E8=83=BD=E4=BC=9A=E5=9C=A8=E5=90=8E=E5=8F=B0=E8=A7=A6?= =?UTF-8?q?=E5=8F=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/common/utils/status_bar_tap.dart | 10 ++++++++++ lib/pages/member/view.dart | 12 ++++++++++++ lib/pages/video/view.dart | 12 ++++++++++++ 3 files changed, 34 insertions(+) diff --git a/lib/common/utils/status_bar_tap.dart b/lib/common/utils/status_bar_tap.dart index e8e6a7f129..8965d19bb5 100644 --- a/lib/common/utils/status_bar_tap.dart +++ b/lib/common/utils/status_bar_tap.dart @@ -19,6 +19,9 @@ class StatusBarTapObserver with WidgetsBindingObserver { /// 当前页面的路由名,用于判断是否在前台。 String? routeName; + /// 当前应用生命周期状态 + AppLifecycleState _lifecycleState = AppLifecycleState.resumed; + StatusBarTapObserver register() { WidgetsBinding.instance.addObserver(this); return this; @@ -33,8 +36,15 @@ class StatusBarTapObserver with WidgetsBindingObserver { if (!Pref.enableStatusBarTapToTop) return; if (routeName == null) return; if (Get.currentRoute != routeName) return; + // 仅在应用处于前台(resumed)时触发 + if (_lifecycleState != AppLifecycleState.resumed) return; if (scrollController.hasClients) { animateToTop(); } } + + @override + void didChangeAppLifecycleState(AppLifecycleState state) { + _lifecycleState = state; + } } diff --git a/lib/pages/member/view.dart b/lib/pages/member/view.dart index 6b9fd6bbdc..1b8a29cf14 100644 --- a/lib/pages/member/view.dart +++ b/lib/pages/member/view.dart @@ -28,6 +28,7 @@ import 'package:PiliPlus/pages/member_video_web/archive/view.dart'; import 'package:PiliPlus/pages/member_video_web/season_series/view.dart'; import 'package:PiliPlus/utils/date_utils.dart'; import 'package:PiliPlus/utils/page_utils.dart'; +import 'package:PiliPlus/utils/storage_pref.dart'; import 'package:PiliPlus/utils/utils.dart'; import 'package:extended_nested_scroll_view/extended_nested_scroll_view.dart'; import 'package:flutter/foundation.dart' show kDebugMode; @@ -52,6 +53,14 @@ class _MemberPageState extends State with WidgetsBindingObserver { PageController getHeaderController() => _headerController ??= PageController(); + /// 当前应用生命周期状态 + AppLifecycleState _lifecycleState = AppLifecycleState.resumed; + + @override + void didChangeAppLifecycleState(AppLifecycleState state) { + _lifecycleState = state; + } + @override void initState() { super.initState(); @@ -76,7 +85,10 @@ class _MemberPageState extends State with WidgetsBindingObserver { @override void handleStatusBarTap() { + if (!Pref.enableStatusBarTapToTop) return; if (Get.currentRoute != _routeName) return; + // 仅在应用处于前台(resumed)时触发 + if (_lifecycleState != AppLifecycleState.resumed) return; final outerCtr = _userController.key.currentState?.outerController; if (outerCtr?.hasClients == true) { outerCtr!.animateTo( diff --git a/lib/pages/video/view.dart b/lib/pages/video/view.dart index 04d42f2241..5fdd520e16 100644 --- a/lib/pages/video/view.dart +++ b/lib/pages/video/view.dart @@ -63,6 +63,7 @@ import 'package:PiliPlus/utils/page_utils.dart'; import 'package:PiliPlus/utils/platform_utils.dart'; import 'package:PiliPlus/utils/storage.dart'; import 'package:PiliPlus/utils/storage_key.dart'; +import 'package:PiliPlus/utils/storage_pref.dart'; import 'package:auto_orientation/auto_orientation.dart'; import 'package:extended_nested_scroll_view/extended_nested_scroll_view.dart'; import 'package:floating/floating.dart'; @@ -140,6 +141,14 @@ class _VideoDetailPageVState extends State Worker? _pipModeWorker; + /// 当前应用生命周期状态 + AppLifecycleState _lifecycleState = AppLifecycleState.resumed; + + @override + void didChangeAppLifecycleState(AppLifecycleState state) { + _lifecycleState = state; + } + @override void initState() { super.initState(); @@ -231,7 +240,10 @@ class _VideoDetailPageVState extends State @override void handleStatusBarTap() { + if (!Pref.enableStatusBarTapToTop) return; if (!isShowing) return; + // 仅在应用处于前台(resumed)时触发 + if (_lifecycleState != AppLifecycleState.resumed) return; if (videoDetailController.scrollCtr.hasClients) { videoDetailController.animToTop(); } From 946173019c1c2d8521ad943e774be6299275f21f Mon Sep 17 00:00:00 2001 From: cnoim Date: Mon, 27 Jul 2026 17:03:02 +0800 Subject: [PATCH 2/7] =?UTF-8?q?=E5=8E=BB=E9=99=A4=E6=AE=8B=E7=95=99?= =?UTF-8?q?=E7=9A=84cached=5Fnetwork=5Fimage=E4=BB=A3=E7=A0=81=E7=9B=B8?= =?UTF-8?q?=E5=85=B3=E4=BE=9D=E8=B5=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../image/cached_network_svg_image.dart | 3 +- .../publish/common_rich_text_pub_page.dart | 4 +-- .../live_room/superchat/superchat_card.dart | 2 +- lib/plugin/pl_player/view/view.dart | 3 +- lib/services/download/download_service.dart | 2 +- lib/utils/cache_manager_ext.dart | 28 +++++++++++++++++++ lib/utils/image_utils.dart | 2 +- pubspec.lock | 26 +---------------- pubspec.yaml | 4 +-- 9 files changed, 39 insertions(+), 35 deletions(-) create mode 100644 lib/utils/cache_manager_ext.dart diff --git a/lib/common/widgets/image/cached_network_svg_image.dart b/lib/common/widgets/image/cached_network_svg_image.dart index f287a77bfd..8d2bf2e924 100644 --- a/lib/common/widgets/image/cached_network_svg_image.dart +++ b/lib/common/widgets/image/cached_network_svg_image.dart @@ -2,10 +2,11 @@ import 'dart:developer'; +import 'package:PiliPlus/utils/cache_manager_ext.dart'; +import 'package:cached_network_image_ce/cached_network_image.dart'; import 'package:flutter/foundation.dart' show kDebugMode; import 'package:flutter/material.dart'; import 'package:flutter/scheduler.dart'; -import 'package:flutter_cache_manager/flutter_cache_manager.dart'; import 'package:flutter_svg/flutter_svg.dart'; class CachedNetworkSVGImage extends StatefulWidget { diff --git a/lib/pages/common/publish/common_rich_text_pub_page.dart b/lib/pages/common/publish/common_rich_text_pub_page.dart index 7c99d36827..9fa9ab4627 100644 --- a/lib/pages/common/publish/common_rich_text_pub_page.dart +++ b/lib/pages/common/publish/common_rich_text_pub_page.dart @@ -14,6 +14,7 @@ import 'package:PiliPlus/models_new/emote/emote.dart' as e; import 'package:PiliPlus/models_new/live/live_emote/emoticon.dart'; import 'package:PiliPlus/pages/common/publish/common_publish_page.dart'; import 'package:PiliPlus/pages/dynamics_mention/view.dart'; +import 'package:PiliPlus/utils/cache_manager_ext.dart'; import 'package:PiliPlus/utils/extension/file_ext.dart'; import 'package:PiliPlus/utils/extension/num_ext.dart'; import 'package:PiliPlus/utils/extension/string_ext.dart'; @@ -22,13 +23,12 @@ import 'package:PiliPlus/utils/feed_back.dart'; import 'package:PiliPlus/utils/image_utils.dart'; import 'package:PiliPlus/utils/page_utils.dart'; import 'package:PiliPlus/utils/platform_utils.dart'; -import 'package:cached_network_image/cached_network_image.dart'; +import 'package:cached_network_image_ce/cached_network_image.dart'; import 'package:dio/dio.dart' show CancelToken; import 'package:easy_debounce/easy_throttle.dart'; import 'package:flutter/foundation.dart' show kDebugMode; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; -import 'package:flutter_cache_manager/flutter_cache_manager.dart'; import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; import 'package:get/get.dart'; import 'package:image_cropper/image_cropper.dart'; diff --git a/lib/pages/live_room/superchat/superchat_card.dart b/lib/pages/live_room/superchat/superchat_card.dart index c26681214e..1e33de02d5 100644 --- a/lib/pages/live_room/superchat/superchat_card.dart +++ b/lib/pages/live_room/superchat/superchat_card.dart @@ -9,7 +9,7 @@ import 'package:PiliPlus/utils/image_utils.dart'; import 'package:PiliPlus/utils/page_utils.dart'; import 'package:PiliPlus/utils/platform_utils.dart'; import 'package:PiliPlus/utils/utils.dart'; -import 'package:cached_network_image/cached_network_image.dart'; +import 'package:cached_network_image_ce/cached_network_image.dart'; import 'package:flutter/foundation.dart' show kDebugMode; import 'package:flutter/material.dart' hide SelectionArea; import 'package:get/get.dart'; diff --git a/lib/plugin/pl_player/view/view.dart b/lib/plugin/pl_player/view/view.dart index 9b00492c87..66b1e6c286 100644 --- a/lib/plugin/pl_player/view/view.dart +++ b/lib/plugin/pl_player/view/view.dart @@ -52,6 +52,7 @@ import 'package:PiliPlus/plugin/pl_player/widgets/common_btn.dart'; import 'package:PiliPlus/plugin/pl_player/widgets/forward_seek.dart'; import 'package:PiliPlus/plugin/pl_player/widgets/mpv_convert_webp.dart'; import 'package:PiliPlus/plugin/pl_player/widgets/play_pause_btn.dart'; +import 'package:PiliPlus/utils/cache_manager_ext.dart'; import 'package:PiliPlus/utils/duration_utils.dart'; import 'package:PiliPlus/utils/extension/num_ext.dart'; import 'package:PiliPlus/utils/extension/theme_ext.dart'; @@ -64,6 +65,7 @@ import 'package:PiliPlus/utils/storage.dart'; import 'package:PiliPlus/utils/storage_key.dart'; import 'package:PiliPlus/utils/storage_pref.dart'; import 'package:PiliPlus/utils/utils.dart'; +import 'package:cached_network_image_ce/cached_network_image.dart'; import 'package:canvas_danmaku/canvas_danmaku.dart'; import 'package:collection/collection.dart'; import 'package:easy_debounce/easy_throttle.dart'; @@ -74,7 +76,6 @@ import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart' show RenderProxyBox, SemanticsConfiguration; import 'package:flutter/services.dart'; -import 'package:flutter_cache_manager/flutter_cache_manager.dart'; import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; import 'package:flutter_volume_controller/flutter_volume_controller.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; diff --git a/lib/services/download/download_service.dart b/lib/services/download/download_service.dart index 1d469da0db..2839cfc8ec 100644 --- a/lib/services/download/download_service.dart +++ b/lib/services/download/download_service.dart @@ -20,8 +20,8 @@ import 'package:PiliPlus/utils/extension/file_ext.dart'; import 'package:PiliPlus/utils/extension/string_ext.dart'; import 'package:PiliPlus/utils/id_utils.dart'; import 'package:PiliPlus/utils/path_utils.dart'; +import 'package:cached_network_image_ce/cached_network_image.dart'; import 'package:flutter/foundation.dart'; -import 'package:flutter_cache_manager/flutter_cache_manager.dart'; import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; import 'package:get/get.dart'; import 'package:path/path.dart' as path; diff --git a/lib/utils/cache_manager_ext.dart b/lib/utils/cache_manager_ext.dart new file mode 100644 index 0000000000..ca038c1533 --- /dev/null +++ b/lib/utils/cache_manager_ext.dart @@ -0,0 +1,28 @@ +import 'dart:io'; + +import 'package:cached_network_image_ce/cached_network_image.dart'; +import 'package:stream_transform/stream_transform.dart'; + +/// Extension on [BaseCacheManager] to provide a [getSingleFile] convenience +/// method, which was available in flutter_cache_manager but is not included +/// in cached_network_image_ce's BaseCacheManager. +extension CacheManagerGetSingleFile on BaseCacheManager { + /// Returns a [Future] of the cached or newly downloaded file. + /// + /// This is functionally equivalent to the old `getSingleFile` from + /// flutter_cache_manager: it streams the file (from cache or network) + /// and returns the first [FileInfo]'s [File]. + Future getSingleFile( + String url, { + String? key, + Map? headers, + }) async { + final fileInfo = await getFileStream( + url, + key: key, + headers: headers, + withProgress: false, + ).whereType().first; + return fileInfo.file; + } +} diff --git a/lib/utils/image_utils.dart b/lib/utils/image_utils.dart index 6a0504963a..338f6a90a0 100644 --- a/lib/utils/image_utils.dart +++ b/lib/utils/image_utils.dart @@ -12,10 +12,10 @@ import 'package:PiliPlus/utils/permission_handler.dart'; import 'package:PiliPlus/utils/platform_utils.dart'; import 'package:PiliPlus/utils/storage_pref.dart'; import 'package:PiliPlus/utils/utils.dart'; +import 'package:cached_network_image_ce/cached_network_image.dart'; import 'package:dio/dio.dart'; import 'package:file_picker/file_picker.dart'; import 'package:flutter/material.dart'; -import 'package:flutter_cache_manager/flutter_cache_manager.dart'; import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; import 'package:intl/intl.dart' show DateFormat; import 'package:live_photo_maker/live_photo_maker.dart'; diff --git a/pubspec.lock b/pubspec.lock index b6f948c1c7..7c01e875db 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -244,14 +244,6 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "8.12.6" - cached_network_image: - dependency: "direct main" - description: - name: cached_network_image - sha256: "7c1183e361e5c8b0a0f21a28401eecdbde252441106a9816400dd4c2b2424916" - url: "https://pub.flutter-io.cn" - source: hosted - version: "3.4.1" cached_network_image_ce: dependency: "direct main" description: @@ -260,14 +252,6 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "4.9.0" - cached_network_image_platform_interface: - dependency: transitive - description: - name: cached_network_image_platform_interface - sha256: "35814b016e37fbdc91f7ae18c8caf49ba5c88501813f73ce8a07027a395e2829" - url: "https://pub.flutter-io.cn" - source: hosted - version: "4.1.1" cached_network_image_platform_interface_ce: dependency: transitive description: @@ -276,14 +260,6 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "5.2.0" - cached_network_image_web: - dependency: transitive - description: - name: cached_network_image_web - sha256: "980842f4e8e2535b8dbd3d5ca0b1f0ba66bf61d14cc3a17a9b4788a3685ba062" - url: "https://pub.flutter-io.cn" - source: hosted - version: "1.3.1" cached_network_image_web_ce: dependency: transitive description: @@ -672,7 +648,7 @@ packages: source: sdk version: "0.0.0" flutter_cache_manager: - dependency: "direct main" + dependency: transitive description: name: flutter_cache_manager sha256: "400b6592f16a4409a7f2bb929a9a7e38c72cceb8ffb99ee57bbf2cb2cecf8386" diff --git a/pubspec.yaml b/pubspec.yaml index 8d52043155..5c0ba5df56 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -17,7 +17,7 @@ publish_to: "none" # Remove this line if you wish to publish to pub.dev # In Windows, build-name is used as the major, minor, and patch parts # of the product and file versions while build-number is used as the build suffix. # update when release -version: 2.0.2+1 +version: 2.0.2+5218 environment: sdk: ">=3.11.1" @@ -56,7 +56,6 @@ dependencies: dio_http2_adapter: ^2.7.1 # 图片 - cached_network_image: ^3.4.1 # extended_image: ^9.0.7 saver_gallery: ^4.1.0 # 已适配鸿蒙 @@ -259,7 +258,6 @@ dependencies: path: any collection: any material_color_utilities: any - flutter_cache_manager: any http2: any screen_retriever: any characters: any From 2721e814052d78e2f26393d18a7e2c54888c5e15 Mon Sep 17 00:00:00 2001 From: cnoim Date: Mon, 27 Jul 2026 17:03:17 +0800 Subject: [PATCH 3/7] =?UTF-8?q?=E5=9B=BE=E7=89=87=E9=99=8D=E5=86=85?= =?UTF-8?q?=E5=AD=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../widgets/image/network_img_layer.dart | 52 +++++++++---------- 1 file changed, 25 insertions(+), 27 deletions(-) diff --git a/lib/common/widgets/image/network_img_layer.dart b/lib/common/widgets/image/network_img_layer.dart index 69d7500846..511e26812d 100644 --- a/lib/common/widgets/image/network_img_layer.dart +++ b/lib/common/widgets/image/network_img_layer.dart @@ -71,33 +71,31 @@ class NetworkImgLayer extends StatelessWidget { memCacheHeight = height.cacheSize(context); } - return RepaintBoundary( - child: CachedNetworkImage( - imageUrl: (isEmote) - ? ImageUtils.thumbnailUrl(src, quality) - : ImageUtils.thumbnailUrlWithSize( - src, - memCacheWidth, - memCacheHeight, - quality, - ), - width: width, - height: height, - memCacheWidth: memCacheWidth, - memCacheHeight: memCacheHeight, - fit: fit, - alignment: alignment, - fadeOutDuration: fadeOutDuration, - fadeInDuration: fadeInDuration, - filterQuality: FilterQuality.low, - placeholder: (_, _) => - getPlaceHolder?.call() ?? - _placeholder(context, isEmote: isEmote, isAvatar: isAvatar), - errorBuilder: (_, _, _) => - _placeholder(context, isEmote: isEmote, isAvatar: isAvatar), - colorBlendMode: reduce ? BlendMode.modulate : null, - color: reduce ? reduceLuxColor : null, - ), + return CachedNetworkImage( + imageUrl: (isEmote) + ? ImageUtils.thumbnailUrl(src, quality) + : ImageUtils.thumbnailUrlWithSize( + src, + memCacheWidth, + memCacheHeight, + quality, + ), + width: width, + height: height, + memCacheWidth: memCacheWidth, + memCacheHeight: memCacheHeight, + fit: fit, + alignment: alignment, + fadeOutDuration: fadeOutDuration, + fadeInDuration: fadeInDuration, + filterQuality: FilterQuality.low, + placeholder: (_, _) => + getPlaceHolder?.call() ?? + _placeholder(context, isEmote: isEmote, isAvatar: isAvatar), + errorBuilder: (_, _, _) => + _placeholder(context, isEmote: isEmote, isAvatar: isAvatar), + colorBlendMode: reduce ? BlendMode.modulate : null, + color: reduce ? reduceLuxColor : null, ); } From 296be7bd8a0edaac6be700bff4b124a1f2ed8542 Mon Sep 17 00:00:00 2001 From: cnoim Date: Mon, 27 Jul 2026 17:03:33 +0800 Subject: [PATCH 4/7] =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=AD=97=E4=BD=93?= =?UTF-8?q?=E8=B7=9F=E9=9A=8F=E7=B2=97=E7=BB=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/utils/theme_utils.dart | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/lib/utils/theme_utils.dart b/lib/utils/theme_utils.dart index 49b54ec05a..ee5b0aec54 100644 --- a/lib/utils/theme_utils.dart +++ b/lib/utils/theme_utils.dart @@ -48,12 +48,10 @@ abstract final class ThemeUtils { fontWeight = FontWeight.w500; } else if (systemScale <= 1.3) { fontWeight = FontWeight.w600; - } else if (systemScale <= 1.35) { - fontWeight = FontWeight.w700; } else if (systemScale <= 1.45) { - fontWeight = FontWeight.w800; + fontWeight = FontWeight.w700; } else { - fontWeight = FontWeight.w900; + fontWeight = FontWeight.w800; } } else { fontWeight = FontWeight.values[appFontWeight]; From a39f9c2fcc3a4cc9bbc030522bdaebed7f5ff7dc Mon Sep 17 00:00:00 2001 From: cnoim Date: Mon, 27 Jul 2026 17:09:16 +0800 Subject: [PATCH 5/7] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E7=BC=96=E8=AF=91?= =?UTF-8?q?=E6=8A=A5=E9=94=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/pages/video/view.dart | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/lib/pages/video/view.dart b/lib/pages/video/view.dart index 5fdd520e16..896cc32786 100644 --- a/lib/pages/video/view.dart +++ b/lib/pages/video/view.dart @@ -144,11 +144,6 @@ class _VideoDetailPageVState extends State /// 当前应用生命周期状态 AppLifecycleState _lifecycleState = AppLifecycleState.resumed; - @override - void didChangeAppLifecycleState(AppLifecycleState state) { - _lifecycleState = state; - } - @override void initState() { super.initState(); @@ -210,6 +205,7 @@ class _VideoDetailPageVState extends State @override void didChangeAppLifecycleState(AppLifecycleState state) { + _lifecycleState = state; late final ctr = videoDetailController.plPlayerController; if (state == AppLifecycleState.resumed) { if (!ctr.showDanmaku) { From 2336ecef2c6311f53590a38aaf7547bdd44d6520 Mon Sep 17 00:00:00 2001 From: cnoim Date: Tue, 28 Jul 2026 16:19:05 +0800 Subject: [PATCH 6/7] =?UTF-8?q?=E6=9B=B4=E6=96=B0libmpv=E5=BA=93=EF=BC=8C?= =?UTF-8?q?=E4=BC=98=E5=8C=96=E8=A7=86=E9=A2=91=E8=A7=A3=E7=A0=81=E6=80=A7?= =?UTF-8?q?=E8=83=BD=EF=BC=8C=E4=BF=AE=E5=A4=8D=E5=86=85=E5=AD=98=E6=B3=84?= =?UTF-8?q?=E6=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/pages/live_room/view.dart | 8 ++-- lib/pages/video/view.dart | 16 +++---- lib/pages/video/widgets/header_control.dart | 6 +-- lib/plugin/pl_player/controller.dart | 12 ++--- pubspec.lock | 50 ++++++++++----------- pubspec.yaml | 27 ++++++----- 6 files changed, 63 insertions(+), 56 deletions(-) diff --git a/lib/pages/live_room/view.dart b/lib/pages/live_room/view.dart index f2c1db150d..220db428d2 100644 --- a/lib/pages/live_room/view.dart +++ b/lib/pages/live_room/view.dart @@ -1,4 +1,5 @@ -import 'dart:io'; +import 'dart:async'; +import 'dart:io'; import 'dart:math'; import 'dart:ui'; @@ -171,9 +172,8 @@ class _LiveRoomPageState extends State ScreenBrightnessPlatform.instance.resetApplicationScreenBrightness(); } PlPlayerController.setPlayCallBack(null); - plPlayerController - ..removeStatusLister(playerListener) - ..dispose(); + plPlayerController.removeStatusLister(playerListener); + unawaited(plPlayerController.dispose()); for (final e in LiveContributionRankType.values) { Get.delete( tag: '${_liveRoomController.roomId}${e.name}', diff --git a/lib/pages/video/view.dart b/lib/pages/video/view.dart index 896cc32786..8f3222a20d 100644 --- a/lib/pages/video/view.dart +++ b/lib/pages/video/view.dart @@ -404,7 +404,7 @@ class _VideoDetailPageVState extends State videoPlayerServiceHandler?.onVideoDetailDispose(heroTag); if (plPlayerController != null) { videoDetailController.makeHeartBeat(); - plPlayerController!.dispose(); + unawaited(plPlayerController!.dispose()); } else { PlPlayerController.updatePlayCount(); } @@ -745,10 +745,10 @@ class _VideoDetailPageVState extends State .onSurface, ), onPressed: () { - videoDetailController - .plPlayerController - ..isCloseAll = true - ..dispose(); + final plCtr = videoDetailController + .plPlayerController; + plCtr.isCloseAll = true; + unawaited(plCtr.dispose()); Get.until( (route) => route.isFirst, ); @@ -1283,9 +1283,9 @@ class _VideoDetailPageVState extends State ], ), onPressed: () { - videoDetailController.plPlayerController - ..isCloseAll = true - ..dispose(); + final plCtr = videoDetailController.plPlayerController; + plCtr.isCloseAll = true; + unawaited(plCtr.dispose()); Get.until((route) => route.isFirst); }, ), diff --git a/lib/pages/video/widgets/header_control.dart b/lib/pages/video/widgets/header_control.dart index cb5487d35f..ba0a5f312a 100644 --- a/lib/pages/video/widgets/header_control.dart +++ b/lib/pages/video/widgets/header_control.dart @@ -1792,9 +1792,9 @@ class HeaderControlState extends State color: Colors.white, ), onPressed: () { - videoDetailCtr.plPlayerController - ..isCloseAll = true - ..dispose(); + final plCtr = videoDetailCtr.plPlayerController; + plCtr.isCloseAll = true; + unawaited(plCtr.dispose()); Get.until((route) => route.isFirst); }, ), diff --git a/lib/plugin/pl_player/controller.dart b/lib/plugin/pl_player/controller.dart index d87301b00b..cded2937cc 100644 --- a/lib/plugin/pl_player/controller.dart +++ b/lib/plugin/pl_player/controller.dart @@ -670,7 +670,7 @@ class PlPlayerController with BlockConfigMixin { if (_playerCount == 0) { _removeListeners(); - _videoPlayerController?.dispose(); + await _videoPlayerController?.dispose(); _videoPlayerController = null; _videoController = null; return; @@ -824,7 +824,7 @@ class PlPlayerController with BlockConfigMixin { player = await _initPlayer(); if (_playerCount == 0) { _removeListeners(); - player.dispose(); + await player.dispose(); player = null; _videoController = null; return; @@ -1768,7 +1768,7 @@ class PlPlayerController with BlockConfigMixin { } bool isCloseAll = false; - void dispose() { + Future dispose() async { // 每次减1,最后销毁 cancelLongPressTimer(); _cancelSubForSeek(); @@ -1817,7 +1817,7 @@ class PlPlayerController with BlockConfigMixin { if (kDebugMode) { debugPrint('dispose player'); } - _videoPlayerController?.dispose(); + await _videoPlayerController?.dispose(); _videoPlayerController = null; _videoController = null; _instance = null; @@ -1825,9 +1825,9 @@ class PlPlayerController with BlockConfigMixin { HarmonyChannel.releaseContinuation(this); } - static void updatePlayCount() { + static Future updatePlayCount() async { if (_instance?._playerCount == 1) { - _instance?.dispose(); + await _instance?.dispose(); } else { _instance?._playerCount -= 1; } diff --git a/pubspec.lock b/pubspec.lock index 7c01e875db..b3c5a88c62 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1259,11 +1259,11 @@ packages: dependency: "direct main" description: path: media_kit - ref: HEAD - resolved-ref: df5a969e617a1ce038d5cca46bedcfa1970a7dc6 - url: "https://github.com/Predidit/media-kit.git" + ref: feat-ohos + resolved-ref: "9de37e13e54953c860d47429f18da6fc096e8992" + url: "https://github.com/cnoim/media-kit.git" source: git - version: "1.1.11" + version: "1.2.3" media_kit_libs_android_video: dependency: "direct overridden" description: @@ -1277,47 +1277,47 @@ packages: dependency: "direct overridden" description: path: "libs/ios/media_kit_libs_ios_video" - ref: HEAD - resolved-ref: df5a969e617a1ce038d5cca46bedcfa1970a7dc6 - url: "https://github.com/Predidit/media-kit.git" + ref: feat-ohos + resolved-ref: "9de37e13e54953c860d47429f18da6fc096e8992" + url: "https://github.com/cnoim/media-kit.git" source: git version: "1.1.4" media_kit_libs_linux: dependency: "direct overridden" description: path: "libs/linux/media_kit_libs_linux" - ref: HEAD - resolved-ref: df5a969e617a1ce038d5cca46bedcfa1970a7dc6 - url: "https://github.com/Predidit/media-kit.git" + ref: feat-ohos + resolved-ref: "9de37e13e54953c860d47429f18da6fc096e8992" + url: "https://github.com/cnoim/media-kit.git" source: git - version: "1.1.3" + version: "1.2.1" media_kit_libs_macos_video: dependency: "direct overridden" description: path: "libs/macos/media_kit_libs_macos_video" - ref: HEAD - resolved-ref: df5a969e617a1ce038d5cca46bedcfa1970a7dc6 - url: "https://github.com/Predidit/media-kit.git" + ref: feat-ohos + resolved-ref: "9de37e13e54953c860d47429f18da6fc096e8992" + url: "https://github.com/cnoim/media-kit.git" source: git version: "1.1.4" media_kit_libs_ohos: dependency: "direct overridden" description: path: "libs/ohos/media_kit_libs_ohos" - ref: HEAD - resolved-ref: df5a969e617a1ce038d5cca46bedcfa1970a7dc6 - url: "https://github.com/Predidit/media-kit.git" + ref: feat-ohos + resolved-ref: "9de37e13e54953c860d47429f18da6fc096e8992" + url: "https://github.com/cnoim/media-kit.git" source: git version: "1.0.0" media_kit_libs_video: dependency: "direct main" description: path: "libs/universal/media_kit_libs_video" - ref: HEAD - resolved-ref: df5a969e617a1ce038d5cca46bedcfa1970a7dc6 - url: "https://github.com/Predidit/media-kit.git" + ref: feat-ohos + resolved-ref: "9de37e13e54953c860d47429f18da6fc096e8992" + url: "https://github.com/cnoim/media-kit.git" source: git - version: "1.0.5" + version: "1.0.7" media_kit_libs_windows_video: dependency: "direct overridden" description: @@ -1340,11 +1340,11 @@ packages: dependency: "direct main" description: path: media_kit_video - ref: HEAD - resolved-ref: df5a969e617a1ce038d5cca46bedcfa1970a7dc6 - url: "https://github.com/Predidit/media-kit.git" + ref: feat-ohos + resolved-ref: "9de37e13e54953c860d47429f18da6fc096e8992" + url: "https://github.com/cnoim/media-kit.git" source: git - version: "1.2.5" + version: "2.0.1" menu_base: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 5c0ba5df56..60a4216991 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -17,7 +17,7 @@ publish_to: "none" # Remove this line if you wish to publish to pub.dev # In Windows, build-name is used as the major, minor, and patch parts # of the product and file versions while build-number is used as the build suffix. # update when release -version: 2.0.2+5218 +version: 2.0.2+5223 environment: sdk: ">=3.11.1" @@ -116,11 +116,13 @@ dependencies: media_kit: # overridden media_kit_video: git: - url: https://github.com/Predidit/media-kit.git + url: https://github.com/cnoim/media-kit.git + ref: feat-ohos path: ./media_kit_video media_kit_libs_video: git: - url: https://github.com/Predidit/media-kit.git + url: https://github.com/cnoim/media-kit.git + ref: feat-ohos path: ./libs/universal/media_kit_libs_video # 媒体通知 @@ -303,31 +305,36 @@ dependency_overrides: rxdart: ^0.28.0 media_kit: git: - url: https://github.com/Predidit/media-kit.git + url: https://github.com/cnoim/media-kit.git + ref: feat-ohos path: ./media_kit media_kit_libs_linux: git: - url: https://github.com/Predidit/media-kit.git + url: https://github.com/cnoim/media-kit.git + ref: feat-ohos path: ./libs/linux/media_kit_libs_linux media_kit_libs_ios_video: git: - url: https://github.com/Predidit/media-kit.git + url: https://github.com/cnoim/media-kit.git + ref: feat-ohos path: ./libs/ios/media_kit_libs_ios_video media_kit_libs_macos_video: git: - url: https://github.com/Predidit/media-kit.git + url: https://github.com/cnoim/media-kit.git + ref: feat-ohos path: ./libs/macos/media_kit_libs_macos_video media_kit_libs_ohos: git: - url: https://github.com/Predidit/media-kit.git + url: https://github.com/cnoim/media-kit.git + ref: feat-ohos path: ./libs/ohos/media_kit_libs_ohos # media_kit_libs_android_video: # git: - # url: https://github.com/Predidit/media-kit.git + # url: https://github.com/cnoim/media-kit.git # path: ./libs/android/media_kit_libs_android_video # media_kit_libs_windows_video: # git: - # url: https://github.com/Predidit/media-kit.git + # url: https://github.com/cnoim/media-kit.git # path: ./libs/windows/media_kit_libs_windows_video # 上游指定的media_kit From 54693cc8c41353dca7242ac073a0862db3981984 Mon Sep 17 00:00:00 2001 From: cnoim Date: Tue, 28 Jul 2026 22:49:55 +0800 Subject: [PATCH 7/7] =?UTF-8?q?=E5=BA=94=E7=94=A8=E9=80=80=E5=90=8E?= =?UTF-8?q?=E5=8F=B0=E6=B8=85=E7=90=86=E5=9B=BE=E7=89=87=E7=BC=93=E5=AD=98?= =?UTF-8?q?=EF=BC=8C=E9=99=8D=E5=90=8E=E5=8F=B0=E5=86=85=E5=AD=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/main.dart | 3 +++ lib/utils/image_memory_cleaner.dart | 32 +++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+) create mode 100644 lib/utils/image_memory_cleaner.dart diff --git a/lib/main.dart b/lib/main.dart index d8fa477289..b441d1b43f 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -19,6 +19,7 @@ import 'package:PiliPlus/utils/calc_window_position.dart'; import 'package:PiliPlus/utils/date_utils.dart'; import 'package:PiliPlus/utils/extension/iterable_ext.dart'; import 'package:PiliPlus/utils/extension/theme_ext.dart'; +import 'package:PiliPlus/utils/image_memory_cleaner.dart'; import 'package:PiliPlus/utils/json_file_handler.dart'; import 'package:PiliPlus/utils/path_utils.dart'; import 'package:PiliPlus/utils/platform_utils.dart'; @@ -248,6 +249,8 @@ void main() async { runApp(const MyApp()); } + ImageMemoryCleaner.instance.register(); + if (OS.isHarmony) { // 本次启动若由跨设备接续拉起,首帧后取回接续数据并跳转视频页; // 顺带注册 method channel handler,保证热启动接续推送可达 diff --git a/lib/utils/image_memory_cleaner.dart b/lib/utils/image_memory_cleaner.dart new file mode 100644 index 0000000000..704544d860 --- /dev/null +++ b/lib/utils/image_memory_cleaner.dart @@ -0,0 +1,32 @@ + import 'package:flutter/widgets.dart'; + +/// 监听应用生命周期,进入后台后清理 Flutter 内存图片缓存 +class ImageMemoryCleaner with WidgetsBindingObserver { + ImageMemoryCleaner._internal(); + + static final ImageMemoryCleaner instance = ImageMemoryCleaner._internal(); + + void register() { + WidgetsBinding.instance.addObserver(this); + } + + void unregister() { + WidgetsBinding.instance.removeObserver(this); + } + + void clearImageCache() { + try { + PaintingBinding.instance.imageCache.clear(); + } catch (_) { + // 忽略清理过程中的异常 + } + } + + @override + void didChangeAppLifecycleState(AppLifecycleState state) { + if (state == AppLifecycleState.paused || state == AppLifecycleState.detached) { + debugPrint('ImageMemoryCleaner: clear image cache in background'); + clearImageCache(); + } + } +}