From fe4e0bb8fd0cc84db27da6d6dd320fcc207dc5e1 Mon Sep 17 00:00:00 2001 From: Caisking Date: Fri, 27 Feb 2026 15:57:40 +0800 Subject: [PATCH] =?utf8?q?=E4=BF=AE=E5=A4=8D=E7=9B=AE=E6=A0=87=E8=BE=BE?= =?utf8?q?=E6=88=90=E5=BC=B9=E7=AA=97=E6=AD=BB=E6=9C=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- .../src/notify/goal_notification.cpp | 70 ++++++++++++------- 1 file changed, 46 insertions(+), 24 deletions(-) diff --git a/code/sdk/application/wearable/fd272/service/msg_center/src/notify/goal_notification.cpp b/code/sdk/application/wearable/fd272/service/msg_center/src/notify/goal_notification.cpp index d23a0f126..122be794b 100644 --- a/code/sdk/application/wearable/fd272/service/msg_center/src/notify/goal_notification.cpp +++ b/code/sdk/application/wearable/fd272/service/msg_center/src/notify/goal_notification.cpp @@ -19,6 +19,7 @@ #include "goal_notification.h" #include "ui_resource_string.h" #include "traing/Training_UiConfig.h" +#include "graphic_service.h" #include "ConfigModel.h" #include "uicomponents/UIComponents.h" @@ -38,12 +39,13 @@ namespace OHOS #define BUTTONWINOK "buttom_win" - /* 与运动目标达成弹窗一致的动画参数 */ + /* 与运动目标达成弹窗一致的动画参数(与充电动画创建方式一致:路径 + CreateImageInfoArray) */ static constexpr uint16_t GOAL_WIN_IMAGE_POS_X = 173; static constexpr uint16_t GOAL_WIN_IMAGE_POS_Y = 100; static constexpr uint16_t GOAL_WIN_IMAGE_SIZE = 120; static constexpr uint16_t GOAL_WIN_ANIMATOR_FRAMES = 94; static constexpr uint16_t GOAL_WIN_ANIMATOR_SPEED = 30; + static constexpr const char *GoalWinAnimationPaths = "/user/res/Training/training_GIF/win/"; static UIScrollView *getView{nullptr}; @@ -55,10 +57,9 @@ namespace OHOS static UILabelExt *labelpre = nullptr; static UILabelButtonExt *buttonok_ = nullptr; static UIImageAnimatorView *imageAnimator{nullptr}; - /* 与运动目标达成弹窗相同的静态动画资源(文件路径 + ImageAnimatorInfo) */ - static char g_goalWinPaths[GOAL_WIN_ANIMATOR_FRAMES][64]; - static ImageAnimatorInfo g_goalWinAnimatorInfo[GOAL_WIN_ANIMATOR_FRAMES]; - static bool g_goalWinAnimatorInfoInited = false; + /* 与充电动画一致:CreateImageInfoArray + ImageAnimatorInfo 数组 */ + static const ImageInfo **GoalAnimationInfoArray{nullptr}; + static ImageAnimatorInfo GoalAnimationInfo[GOAL_WIN_ANIMATOR_FRAMES]; static osTimerId_t GoalviewShow_timer = NULL; @@ -98,6 +99,11 @@ namespace OHOS delete imageAnimator; imageAnimator = nullptr; } + if (GoalAnimationInfoArray) + { + FreeImageInfoArray(GoalAnimationInfoArray, GoalWinAnimationPaths, GOAL_WIN_ANIMATOR_FRAMES); + GoalAnimationInfoArray = nullptr; + } // if (image_goalview) // { // delete image_goalview; @@ -285,38 +291,47 @@ namespace OHOS InitLabel(labeltag, 70, 215, 326, 97, "label2", tagString.c_str(),DEFAULT_VECTOR_FONT_FILENAME, 80); labeltag->SetTextColor(Color::GetColorFromRGBA(0x4f, 0xc3, 0x4c, 0xff)); labeltag->SetLineBreakMode(UILabel::LINE_BREAK_OSCILLATION); - /* 与运动目标达成弹窗相同的动画绘制:静态 ImageAnimatorInfo + SetImageAnimatorSrc */ - if (!g_goalWinAnimatorInfoInited) - { - for (int i = 0; i < GOAL_WIN_ANIMATOR_FRAMES; i++) - { - snprintf(g_goalWinPaths[i], sizeof(g_goalWinPaths[i]), - "/user/res/Training/training_GIF/win/%d.bin", i + 1); - g_goalWinAnimatorInfo[i].imagePath = g_goalWinPaths[i]; - g_goalWinAnimatorInfo[i].pos.x = GOAL_WIN_IMAGE_POS_X; - g_goalWinAnimatorInfo[i].pos.y = GOAL_WIN_IMAGE_POS_Y; - g_goalWinAnimatorInfo[i].width = GOAL_WIN_IMAGE_SIZE; - g_goalWinAnimatorInfo[i].height = GOAL_WIN_IMAGE_SIZE; - g_goalWinAnimatorInfo[i].imageType = IMG_SRC_FILE_PATH; - } - g_goalWinAnimatorInfoInited = true; - } + /* 与充电动画一致的创建方式:CreateImageInfoArray + ImageAnimatorInfo(IMG_SRC_IMAGE_INFO) + SetPosition/SetImageAnimatorSrc */ if (imageAnimator == nullptr) { imageAnimator = new UIImageAnimatorView(); } - if (imageAnimator != nullptr) + if (GoalAnimationInfoArray == nullptr) + { + GoalAnimationInfoArray = CreateImageInfoArray(GoalWinAnimationPaths, GOAL_WIN_ANIMATOR_FRAMES); + } + if (GoalAnimationInfoArray != nullptr && imageAnimator != nullptr) { - imageAnimator->SetImageAnimatorSrc(g_goalWinAnimatorInfo, + for (uint8_t i = 0; i < GOAL_WIN_ANIMATOR_FRAMES; i++) + { + GoalAnimationInfo[i].imageInfo = GoalAnimationInfoArray[i]; + GoalAnimationInfo[i].imageType = IMG_SRC_IMAGE_INFO; + GoalAnimationInfo[i].pos.x = GOAL_WIN_IMAGE_POS_X; + GoalAnimationInfo[i].pos.y = GOAL_WIN_IMAGE_POS_Y; + GoalAnimationInfo[i].width = GOAL_WIN_IMAGE_SIZE; + GoalAnimationInfo[i].height = GOAL_WIN_IMAGE_SIZE; + } + imageAnimator->SetPosition(GOAL_WIN_IMAGE_POS_X, GOAL_WIN_IMAGE_POS_Y, + GOAL_WIN_IMAGE_SIZE, GOAL_WIN_IMAGE_SIZE); + imageAnimator->SetStyle(STYLE_BACKGROUND_OPA, 0x00); + imageAnimator->SetImageAnimatorSrc(GoalAnimationInfo, GOAL_WIN_ANIMATOR_FRAMES, GOAL_WIN_ANIMATOR_SPEED); imageAnimator->SetRepeat(true); + imageAnimator->SetRepeatTimes(0); + imageAnimator->SetResizeMode(UIImageView::COVER); imageAnimator->Start(); } } static uint8_t GoalviewShowCallBack_FALG = 0; + static void GoalviewShowStopNotifyProc(int data) + { + (void)data; + NotificationManager::GetInstance()->StopNotify(); + } + static void GoalviewShowCallBack(int data) { GoalviewShowCallBack_FALG--; @@ -331,7 +346,14 @@ namespace OHOS } if (GoalviewShowCallBack_FALG == 0) { - NotificationManager::GetInstance()->StopNotify(); + /* 避免在定时器回调里直接 StopNotify:会触发 Freegoalview 并 osTimerDelete 当前定时器,易导致死机/崩溃。 + * 先投递到图形线程执行 StopNotify,回调返回后再在 Freegoalview 中安全删除定时器。 */ + if (GoalviewShow_timer != nullptr) + { + osTimerStop(GoalviewShow_timer); + } + GraphicService::GetInstance()->PostGraphicEvent( + std::bind(GoalviewShowStopNotifyProc, 0)); } } -- 2.17.1