diff --git a/dom/include/dom/animation/animation_manager.h b/dom/include/dom/animation/animation_manager.h index e92274756c0..af60274e547 100644 --- a/dom/include/dom/animation/animation_manager.h +++ b/dom/include/dom/animation/animation_manager.h @@ -62,15 +62,6 @@ class AnimationManager void RemoveVSyncEventListener(); - /** - * When destroying, it is necessary to remove the VSync event, but it should not indirectly create RenderNode due to EndBatch, - * otherwise there will be multi-threading issues between the main thread and the Dom thread. - * Therefore, a new method is needed to differentiate the destruction scenario. - * This has occasionally caused crashes on iOS. - * In the future, there will be better refactoring solutions for the main thread and Dom thread in the destruction scenario, and this method can be deleted. - */ - void RemoveVSyncEventListenerOnRelease(); - void OnDomNodeCreate(const std::vector>& nodes) override; void OnDomNodeUpdate(const std::vector>& nodes) override; void OnDomNodeMove(const std::vector>& nodes) override; diff --git a/dom/include/dom/dom_manager.h b/dom/include/dom/dom_manager.h index 2e7ba8a0baf..9de80ee4f42 100644 --- a/dom/include/dom/dom_manager.h +++ b/dom/include/dom/dom_manager.h @@ -106,7 +106,6 @@ class DomManager : public std::enable_shared_from_this { static void UpdateAnimation(const std::weak_ptr& weak_root_node, std::vector>&& nodes); void EndBatch(const std::weak_ptr& root_node); - void EndBatchOnRelease(const std::weak_ptr& root_node); // 返回0代表失败,正常id从1开始 static void AddEventListener(const std::weak_ptr& weak_root_node, uint32_t dom_id, diff --git a/dom/include/dom/root_node.h b/dom/include/dom/root_node.h index 8b21a769929..a711fc8e578 100644 --- a/dom/include/dom/root_node.h +++ b/dom/include/dom/root_node.h @@ -57,7 +57,6 @@ class RootNode : public DomNode { void UpdateAnimation(std::vector>&& nodes); void CallFunction(uint32_t id, const std::string& name, const DomArgument& param, const CallFunctionCallback& cb); void SyncWithRenderManager(const std::shared_ptr& render_manager); - void SyncWithRenderManagerOnRelease(const std::shared_ptr& render_manager); void DoAndFlushLayout(const std::shared_ptr& render_manager); void AddEvent(uint32_t id, const std::string& event_name); void RemoveEvent(uint32_t id, const std::string& event_name); diff --git a/dom/src/dom/animation/animation_manager.cc b/dom/src/dom/animation/animation_manager.cc index e82dcababc4..66356b9979b 100644 --- a/dom/src/dom/animation/animation_manager.cc +++ b/dom/src/dom/animation/animation_manager.cc @@ -366,22 +366,6 @@ void AnimationManager::RemoveVSyncEventListener() { } } -void AnimationManager::RemoveVSyncEventListenerOnRelease() { - auto root_node = root_node_.lock(); - if (!root_node) { - return; - } - auto weak_dom_manager = root_node->GetDomManager(); - auto dom_manager = weak_dom_manager.lock(); - if (!dom_manager) { - return; - } - if (dom_manager) { - dom_manager->RemoveEventListener(root_node, root_node->GetId(), kVSyncKey, listener_id_); - dom_manager->EndBatchOnRelease(root_node_); - } -} - void AnimationManager::UpdateAnimation(const std::shared_ptr& animation, uint64_t now, std::unordered_map>& update_node_map) { auto animation_id = animation->GetId(); diff --git a/dom/src/dom/dom_manager.cc b/dom/src/dom/dom_manager.cc index db5a9d64ac5..3a9e947dd26 100644 --- a/dom/src/dom/dom_manager.cc +++ b/dom/src/dom/dom_manager.cc @@ -137,20 +137,6 @@ void DomManager::EndBatch(const std::weak_ptr& weak_root_node) { root_node->SyncWithRenderManager(render_manager); } -void DomManager::EndBatchOnRelease(const std::weak_ptr& weak_root_node) { - auto render_manager = render_manager_.lock(); - FOOTSTONE_DCHECK(render_manager); - if (!render_manager) { - return; - } - auto root_node = weak_root_node.lock(); - if (!root_node) { - return; - } - FOOTSTONE_DLOG(INFO) << "[Hippy Statistic] total node size = " << root_node->GetChildCount(); - root_node->SyncWithRenderManagerOnRelease(render_manager); -} - void DomManager::AddEventListener(const std::weak_ptr& weak_root_node, uint32_t dom_id, const std::string& name, uint64_t listener_id, bool use_capture, const EventCallback& cb) { diff --git a/dom/src/dom/root_node.cc b/dom/src/dom/root_node.cc index 5e35e5b67fd..7310b5a087c 100644 --- a/dom/src/dom/root_node.cc +++ b/dom/src/dom/root_node.cc @@ -64,9 +64,7 @@ void RootNode::RemoveEventListener(const std::string& name, uint64_t listener_id RemoveEvent(GetId(), name); } -void RootNode::ReleaseResources() { - animation_manager_->RemoveVSyncEventListenerOnRelease(); -} +void RootNode::ReleaseResources() {} void RootNode::CreateDomNodes(std::vector>&& nodes) { for (const auto& interceptor : interceptors_) { @@ -284,24 +282,6 @@ void RootNode::SyncWithRenderManager(const std::shared_ptr& rende render_manager->EndBatch(GetWeakSelf()); } -void RootNode::SyncWithRenderManagerOnRelease(const std::shared_ptr& render_manager) { - for (auto& event_operation : event_operations_) { - const auto& node = GetNode(event_operation.id); - if (node == nullptr) { - continue; - } - - switch (event_operation.op) { - case EventOperation::Op::kOpRemove: - render_manager->RemoveEventListener(GetWeakSelf(), node, event_operation.name); - break; - default: - break; - } - } - event_operations_.clear(); -} - void RootNode::AddEvent(uint32_t id, const std::string& event_name) { event_operations_.push_back({EventOperation::Op::kOpAdd, id, event_name}); } diff --git a/framework/examples/ios-demo/HippyDemo/HippyConvenientBridge.mm b/framework/examples/ios-demo/HippyDemo/HippyConvenientBridge.mm index 68584e55d10..f18342484a1 100644 --- a/framework/examples/ios-demo/HippyDemo/HippyConvenientBridge.mm +++ b/framework/examples/ios-demo/HippyDemo/HippyConvenientBridge.mm @@ -276,6 +276,7 @@ - (void)dealloc { _demoLoader->Terminate(); } if (_rootNode) { + _nativeRenderManager->RemoveVSyncEventListener(_rootNode); _rootNode->ReleaseResources(); } } diff --git a/renderer/native/android/src/main/java/com/tencent/renderer/NativeRenderer.java b/renderer/native/android/src/main/java/com/tencent/renderer/NativeRenderer.java index 52da257915e..402a1497b29 100644 --- a/renderer/native/android/src/main/java/com/tencent/renderer/NativeRenderer.java +++ b/renderer/native/android/src/main/java/com/tencent/renderer/NativeRenderer.java @@ -59,6 +59,7 @@ import com.tencent.renderer.serialization.Deserializer; import com.tencent.renderer.serialization.Serializer; import com.tencent.renderer.utils.ArrayUtils; +import com.tencent.renderer.utils.ChoreographerUtils; import com.tencent.renderer.utils.DisplayUtils; import com.tencent.renderer.utils.EventUtils.EventType; @@ -404,6 +405,7 @@ public void onResume() { listener.onInstanceResume(); } } + ChoreographerUtils.onResume(); } @Override @@ -413,6 +415,7 @@ public void onPause() { listener.onInstancePause(); } } + ChoreographerUtils.onPause(); } @MainThread @@ -423,6 +426,7 @@ public void destroyRoot(int rootId) { listener.onInstanceDestroy(rootId); } } + ChoreographerUtils.unregisterDoFrameListener(getInstanceId(), rootId); mRenderManager.deleteNode(rootId, rootId); mRenderManager.batch(rootId); } diff --git a/renderer/native/android/src/main/java/com/tencent/renderer/utils/ChoreographerUtils.java b/renderer/native/android/src/main/java/com/tencent/renderer/utils/ChoreographerUtils.java index fc20bbd92f0..c74922a0377 100644 --- a/renderer/native/android/src/main/java/com/tencent/renderer/utils/ChoreographerUtils.java +++ b/renderer/native/android/src/main/java/com/tencent/renderer/utils/ChoreographerUtils.java @@ -26,6 +26,7 @@ public class ChoreographerUtils { public static final String DO_FRAME = "frameUpdate"; private static boolean sEnablePostFrame = false; + private static boolean sInForeground = true; private static HashMap> sListeners = null; private static void handleDoFrameCallback() { @@ -42,18 +43,28 @@ private static void handleDoFrameCallback() { } private static void doPostFrame() { - Choreographer.FrameCallback frameCallback = new Choreographer.FrameCallback() { - @Override - public void doFrame(long frameTimeNanos) { + Choreographer.FrameCallback frameCallback = frameTimeNanos -> { + if (sEnablePostFrame && sInForeground) { handleDoFrameCallback(); - if (sEnablePostFrame) { - doPostFrame(); - } + doPostFrame(); } }; Choreographer.getInstance().postFrameCallback(frameCallback); } + @MainThread + public static void onResume() { + sInForeground = true; + if (sEnablePostFrame) { + doPostFrame(); + } + } + + @MainThread + public static void onPause() { + sInForeground = false; + } + /** * Register frame callback listener, should call in ui thread. * diff --git a/renderer/native/ios/renderer/NativeRenderImpl.h b/renderer/native/ios/renderer/NativeRenderImpl.h index c0b69cad856..1ec5331edd2 100644 --- a/renderer/native/ios/renderer/NativeRenderImpl.h +++ b/renderer/native/ios/renderer/NativeRenderImpl.h @@ -228,6 +228,11 @@ class HippyValue; forDomNodeId:(int32_t)node_id onRootNode:(std::weak_ptr)rootNode; +/** + * unregister vsync event + */ +- (void)removeVSyncEventOnRootNode:(std::weak_ptr)rootNode; + /** * Set root view size changed event callback * diff --git a/renderer/native/ios/renderer/NativeRenderImpl.mm b/renderer/native/ios/renderer/NativeRenderImpl.mm index 87be2c192e0..0787363b653 100644 --- a/renderer/native/ios/renderer/NativeRenderImpl.mm +++ b/renderer/native/ios/renderer/NativeRenderImpl.mm @@ -1386,6 +1386,11 @@ - (void)removeEventName:(const std::string &)eventName } } +- (void)removeVSyncEventOnRootNode:(std::weak_ptr)rootNode { + NSString *vsyncKey = [NSString stringWithFormat:@"%p-%d", self, static_cast(rootNode.lock()->GetId())]; + [[RenderVsyncManager sharedInstance] unregisterVsyncObserverForKey:vsyncKey]; +} + - (void)addPropertyEvent:(const std::string &)name forDomNode:(int32_t)node_id onRootNode:(std::weak_ptr)rootNode { AssertMainQueue(); diff --git a/renderer/native/ios/renderer/NativeRenderManager.h b/renderer/native/ios/renderer/NativeRenderManager.h index 7e7e97384fb..89043bc7e59 100644 --- a/renderer/native/ios/renderer/NativeRenderManager.h +++ b/renderer/native/ios/renderer/NativeRenderManager.h @@ -127,6 +127,11 @@ class NativeRenderManager : public hippy::RenderManager ,public std::enable_shar */ void RemoveEventListener(std::weak_ptr root_node, std::weak_ptr dom_node, const std::string &name) override; + /** + * unregister vsync event + */ + void RemoveVSyncEventListener(std::weak_ptr root_node); + /** * invoke function of view * diff --git a/renderer/native/ios/renderer/NativeRenderManager.mm b/renderer/native/ios/renderer/NativeRenderManager.mm index d654c274056..64124224d20 100644 --- a/renderer/native/ios/renderer/NativeRenderManager.mm +++ b/renderer/native/ios/renderer/NativeRenderManager.mm @@ -146,6 +146,13 @@ } } +void NativeRenderManager::RemoveVSyncEventListener(std::weak_ptr root_node) { + @autoreleasepool { + HPAssert(renderImpl_, @"renderImpl_ is null, did you forget to call Initialize()?"); + [renderImpl_ removeVSyncEventOnRootNode:root_node]; + } +} + void NativeRenderManager::CallFunction(std::weak_ptr root_node, std::weak_ptr dom_node, const std::string &name,