实现导航历史栈功能: 18/1 18/head
authorluozheng <1732036298@qq.com>
Tue, 16 Apr 2024 12:49:06 +0000 (20:49 +0800)
committerluozheng <1732036298@qq.com>
Tue, 16 Apr 2024 12:49:06 +0000 (20:49 +0800)
1.当从一个Slice进入另一个Slice时调用NativeAbility::GetInstance().EnterSlice(sliceId)
2.NativeAbility::GetInstance().Back 处理后退操作
3.ChangeSlice不压栈

code/sdk/application/wearable/fd230app/nativeui/brightnesslevel/src/BrightnessLevelPresenter.cpp
code/sdk/application/wearable/fd230app/nativeui/displaybrightness/src/DisplayBrightnessPresent.cpp
code/sdk/application/wearable/fd230app/nativeui/settings/src/SettingPresenter.cpp
code/sdk/application/wearable/nativeabilityfwk/include/Ability.h
code/sdk/application/wearable/nativeabilityfwk/src/Ability.cpp

index 530f718..bebd55a 100644 (file)
@@ -2,7 +2,7 @@
  * @Author: luozheng 1732036298@qq.com
  * @Date: 2024-04-16 14:36:45
  * @LastEditors: luozheng 1732036298@qq.com
- * @LastEditTime: 2024-04-16 17:30:38
+ * @LastEditTime: 2024-04-16 20:31:07
  * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/brightnesslevel/src/BrightnessLevelPresenter.cpp
  */
 #include "brightnesslevel/include/BrightnessLevelPresenter.h"
@@ -85,8 +85,9 @@ namespace OHOS
         // 如果是power键,且是亮屏状态,按键释放就返回上一级
         if (keyID == static_cast<uint16_t>(ZliteKeyCode::ZLITE_KEY_POWER) && keyState == 0 && uapi_get_screen_state() == 0)
         {
-            uint16_t preSlice = NativeAbility::GetInstance().GetPreSliceId();
-            NativeAbility::GetInstance().ChangeSlice(preSlice);
+            // uint16_t preSlice = NativeAbility::GetInstance().GetPreSliceId();
+            // NativeAbility::GetInstance().ChangeSlice(preSlice);
+            NativeAbility::GetInstance().Back();
         }
         return true;
     }
index a0f2433..050cbee 100644 (file)
@@ -104,7 +104,8 @@ namespace OHOS
         // 根据控件id查找是哪个控件触发了点击回调\r
         if (strcmp(view.GetViewId(), BRINGHTNESSCONTROLBUTTON_VIEW) == 0)\r
         {\r
-            NativeAbility::GetInstance().ChangeSlice(VIEW_BRIGHTNESSLEVEL);\r
+            //NativeAbility::GetInstance().ChangeSlice(VIEW_BRIGHTNESSLEVEL);\r
+            NativeAbility::GetInstance().EnterSlice(VIEW_BRIGHTNESSLEVEL);\r
             return true;\r
         }\r
         if (strcmp(view.GetViewId(), SCREENDURATIONBUTTON_VIEWID) == 0)\r
@@ -172,16 +173,17 @@ namespace OHOS
         // 如果是power键,且是亮屏状态,按键释放就返回上一级\r
         if (keyID == static_cast<uint16_t>(ZliteKeyCode::ZLITE_KEY_POWER) && keyState == 0 && uapi_get_screen_state() == 0)\r
         {\r
-            uint16_t preSlice = NativeAbility::GetInstance().GetPreSliceId();\r
-            if (preSlice == VIEW_BRIGHTNESSLEVEL)\r
-            {\r
-                NativeAbility::GetInstance().ChangeSlice(VIEW_SETTING);\r
-            }\r
-            else\r
-            {\r
+            // uint16_t preSlice = NativeAbility::GetInstance().GetPreSliceId();\r
+            // if (preSlice == VIEW_BRIGHTNESSLEVEL)\r
+            // {\r
+            //     NativeAbility::GetInstance().ChangeSlice(VIEW_SETTING);\r
+            // }\r
+            // else\r
+            // {\r
                 \r
-                NativeAbility::GetInstance().ChangeSlice(preSlice);\r
-            }\r
+            //     NativeAbility::GetInstance().ChangeSlice(preSlice);\r
+            // }\r
+            NativeAbility::GetInstance().Back();\r
         }\r
         return true;\r
     }\r
index 80c802d..24bcea2 100644 (file)
@@ -114,7 +114,8 @@ namespace OHOS
         }
         else
         {
-            NativeAbility::GetInstance().ChangeSlice(SettingModel::GetInstance().GetSettingIdToViewId().at(index));
+            NativeAbility::GetInstance().EnterSlice(SettingModel::GetInstance().GetSettingIdToViewId().at(index));
+            //NativeAbility::GetInstance().ChangeSlice(SettingModel::GetInstance().GetSettingIdToViewId().at(index));
 /* -------------------------------------------------------------------------- */
 #if 0
             if (index == SETTING_ITEM_TWO)
index bdd58b9..77dc388 100755 (executable)
@@ -25,7 +25,8 @@
 #include "wearable_log.h"
 #include "TransitionManager.h"
 #include "SliceTransition.h"
-
+#include "stack"
+#include <AppViewIDs.h>
 namespace OHOS {
 const static uint16_t gSliceInvalid = 0;
 const static uint16_t gSliceDefaultPriority = 4;  // 页面默认是最低优先级
@@ -67,6 +68,27 @@ public:
     uint16_t GetCurSlicePriority(void) {
         return curSlicePriority_;
     }
+
+    // 当从一个Slice进入另一个Slice时调用
+    void EnterSlice(uint16_t sliceId) {
+        // 获取当前SliceID
+        uint16_t curSliceId = GetCurSliceId();
+        if (curSliceId != defaultSliceId_) { // 假定defaultSliceId_是“主页”或启动Slice的ID
+            backStack_.push(curSliceId);
+        }
+        ChangeSlice(sliceId); // 切换到新的Slice
+    }
+
+    // 处理后退操作
+    bool Back() {
+        if (!backStack_.empty()) {
+            uint16_t preSlice = backStack_.top();
+            backStack_.pop();
+            ChangeSlice(preSlice);
+            return true;
+        }
+        return false; // 没有更多的Slice可以后退
+    }
 protected:
     struct ProxyStruct {
         uint16_t sliceId;
@@ -99,7 +121,8 @@ protected:
     void PostChangeSlice(const uint16_t targetSliceId, const uint16_t transitionId, const uint16_t priority);
 
     ListsNode<Ability::ProxyStruct>* Find(const uint16_t sliceId);
-
+private:
+    std::stack<uint16_t> backStack_;//这个栈会在每次进入一个新的Slice时将其ID压入栈顶,当用户请求后退时,栈顶的Slice ID会被弹出,以此来访问前一个Slice。
 };
 }
 #endif // NATIVEABILITYFWK_ABILITY_H
index 20e64c6..77c32d2 100755 (executable)
@@ -18,6 +18,9 @@
 #include "abilityms_slite_client.h"
 
 namespace OHOS {
+/*
+ * @brief 负责将一个SliceProxy对象添加到Ability对象中,如果传入的sliceId是无效的或者代理对象proxy为空,则不执行任何操作。
+ */
 void Ability::AddSliceProxy(const uint16_t sliceId, SliceProxy* proxy)
 {
     WEARABLE_LOGD(WEARABLE_LOG_MODULE_LAUNCHER_FWK, "Ability::AddSliceProxy sliceId = %d", sliceId);
@@ -25,21 +28,29 @@ void Ability::AddSliceProxy(const uint16_t sliceId, SliceProxy* proxy)
         return;
     }
 
+    /*首先,会检查是否已经有一个与传入的sliceId对应的Slice存在,如果存在,则不会添加新的代理。*/
     if (Find(sliceId) != nullptr) {
         return;
     }
 
+    /*如果检查通过,则将sliceId和proxy作为一个结构体添加到allSlicesProxy_列表中,allSlicesProxy_可能是存储所有尚存代理的列表。*/
     Ability::ProxyStruct proxyPair = {sliceId, proxy};
     allSlicesProxy_.PushBack(proxyPair);
 }
 
+/*
+ * @brief 该函数用于启动一个指定ID的Slice。
+ */
 void Ability::StartSlice(const uint16_t sliceId, const uint16_t priority)
 {
     WEARABLE_LOGD(WEARABLE_LOG_MODULE_LAUNCHER_FWK, "Ability::StartSlice sliceId = %d", sliceId);
+    
+    /* ---------------------- 1.首先检查sliceId的有效性,如果无效,则直接返回。 --------------------- */
     if (sliceId <= gSliceInvalid) {
         return;
     }
 
+    /* ---- 2.通过Find函数查找是否已经有对应的SliceProxy存在,如果没有找到对应的代理或创建新Slice实例失败,则不继续执行。 --- */
     ListsNode<Ability::ProxyStruct>* node = Find(sliceId);
     if (node == nullptr) {
         return;
@@ -51,10 +62,11 @@ void Ability::StartSlice(const uint16_t sliceId, const uint16_t priority)
     }
 
     WEARABLE_LOGD(WEARABLE_LOG_MODULE_LAUNCHER_FWK, "Ability::StartSlice Size = %d", allSlices_.size());
-    // 记录最多gMaxHistorySlices个页面id
-    if (allSlices_.size() == gMaxHistorySlices) {
+    /* ----------- 3.记录历史Slice ID,如果历史记录达到最大值gMaxHistorySlices,则移除最旧的记录。 ---------- */
+    if (allSlices_.size() == gMaxHistorySlices) {// 记录最多gMaxHistorySlices个页面id
         allSlices_.erase(allSlices_.begin());
     }
+    /* -------------- 4.设置当前Slice的相关信息,并调用Slice的OnStart和OnResume方法。 ------------- */
     allSlices_.push_back(sliceId);
 
     curSlice_.sliceId = sliceId;
@@ -65,6 +77,9 @@ void Ability::StartSlice(const uint16_t sliceId, const uint16_t priority)
     nextSlice->OnResume();
 }
 
+/*
+ * @brief 释放当前的Slice,将当前Slice对象设置为nullptr,并重置当前Slice ID和优先级 
+ */
 void Ability::ReleaseCurSlice()
 {
     WEARABLE_LOGD(WEARABLE_LOG_MODULE_LAUNCHER_FWK, "Ability::ReleaseCurSlice");
@@ -77,6 +92,9 @@ void Ability::ReleaseCurSlice()
     curSlicePriority_ = gSliceDefaultPriority;
 }
 
+/*
+ * @brief 在allSlicesProxy_列表中寻找与给定sliceId相符合的ProxyStruct节点。如果找到则返回该节点,否则返回nullptr。 
+ */
 ListsNode<Ability::ProxyStruct>* Ability::Find(const uint16_t sliceId)
 {
     if (sliceId <= gSliceInvalid) {
@@ -98,23 +116,39 @@ ListsNode<Ability::ProxyStruct>* Ability::Find(const uint16_t sliceId)
     return nullptr;
 }
 
+/*
+ * @brief 用于改变当前Slice。首先检查切换是否正在进行中;如果是,直接返回。 
+ * @param {uint16_t} targetSliceId
+ * @param {uint16_t} transitionId
+ * @param {uint16_t} priority
+ * @return {*}
+ */
 void Ability::ChangeSlice(const uint16_t targetSliceId, const uint16_t transitionId, const uint16_t priority)
 {
     if (sliceTransition_.IsRunning()) {
         return;
     }
     // onStop释放当前页面需要和当前页面的事件监听异步执行,否则会出现自己杀掉自己的情况
+    //使用图形服务的PostGraphicEvent方法异步执行PostChangeSlice,以避免在页面事件监听时出现当前页面自我销毁的情况。
     GraphicService::GetInstance()->PostGraphicEvent(std::bind(&Ability::PostChangeSlice, this, targetSliceId,
         transitionId, priority));
 }
 
 void Ability::PostChangeSlice(const uint16_t targetSliceId, const uint16_t transitionId, const uint16_t priority)
 {
+    /*
+        1.首先检查当前Slice是否存在,并验证transitionId的有效性。
+        如果当前存在一个有效的Slice,并且transitionId合法,则调用sliceTransition_的SaveCurrentSnapshot方法保存当前Slice的快照,
+        主要是为了后续可能使用的页面转场效果。
+    */
     if (curSlice_.slice != nullptr && transitionId > TRANSITION_INVALID && transitionId < TRANSITION_MAX) {
         sliceTransition_.SaveCurrentSnapshot(curSlice_.slice->GetSliceContainer());
     }
 
     // slice页面跳转,先onstop,再onstart.在一个线程同步执行绘制,不会出现闪屏现象
+    /*
+        2.调用StopSlice函数停止当前Slice的运行。在StopSlice中,会调用当前Slice的OnStop方法,并释放当前Slice占用的资源。
+    */
     StopSlice();
 #ifdef JS_ENABLE
     ElementName *elementName = OHOS::AbilityMsClient::GetInstance().GetTopAbility();
@@ -122,6 +156,11 @@ void Ability::PostChangeSlice(const uint16_t targetSliceId, const uint16_t trans
         OHOS::AbilityMsClient::GetInstance().ForceStop(elementName->bundleName);
        }
 #endif
+    /*
+        调用StartSlice函数以启动新的指定的Slice。
+        StartSlice函数内部会先检查是否存在目标Slice的Proxy,并通过Proxy创建新的实例,
+        记录Slice ID到历史记录中,并调用该Slice的OnStart和OnResume方法开始运行新的Slice。
+    */
     StartSlice(targetSliceId, priority);
     if (transitionId > TRANSITION_INVALID && transitionId < TRANSITION_MAX) {
         sliceTransition_.Transition(curSlice_.slice, TransitionManager::GetTransition(transitionId));
@@ -129,6 +168,9 @@ void Ability::PostChangeSlice(const uint16_t targetSliceId, const uint16_t trans
 
 }
 
+/*
+ * @brief 重新启动当前或默认Slice。根据当前记录的切片历史来决定重启哪个Slice。 
+ */
 void Ability::ResumeSlice(const uint16_t priority)
 {
     uint16_t targetSliceId = gSliceInvalid;
@@ -141,6 +183,9 @@ void Ability::ResumeSlice(const uint16_t priority)
     StartSlice(targetSliceId, priority);
 }
 
+/*
+ * @brief 停止当前的Slice,调用其OnStop方法,并释放当前Slice资源。 
+ */
 void Ability::StopSlice()
 {
     if (curSlice_.slice != nullptr) {