diff --git a/android/sdk/src/main/java/com/taobao/weex/bridge/WXBridge.java b/android/sdk/src/main/java/com/taobao/weex/bridge/WXBridge.java index 482a681fe5..72cf4d74ba 100644 --- a/android/sdk/src/main/java/com/taobao/weex/bridge/WXBridge.java +++ b/android/sdk/src/main/java/com/taobao/weex/bridge/WXBridge.java @@ -467,6 +467,17 @@ public int callCreateFinish(String instanceId) { return errorCode; } + @Override + public int callRenderSuccess(String instanceId) { + int errorCode = IWXBridge.INSTANCE_RENDERING; + try { + errorCode = WXBridgeManager.getInstance().callRenderSuccess(instanceId); + } catch (Throwable e) { + WXLogUtils.e(TAG, "callCreateFinish throw exception:" + e.getMessage()); + } + return errorCode; + } + @Override public int callAppendTreeCreateFinish(String instanceId, String ref) { int errorCode = IWXBridge.INSTANCE_RENDERING; diff --git a/android/sdk/src/main/java/com/taobao/weex/bridge/WXBridgeManager.java b/android/sdk/src/main/java/com/taobao/weex/bridge/WXBridgeManager.java index ab4e6dabf2..02ae49cfab 100644 --- a/android/sdk/src/main/java/com/taobao/weex/bridge/WXBridgeManager.java +++ b/android/sdk/src/main/java/com/taobao/weex/bridge/WXBridgeManager.java @@ -2569,6 +2569,33 @@ public int callCreateFinish(String instanceId) { return IWXBridge.INSTANCE_RENDERING; } + public int callRenderSuccess(String instanceId) { + if (WXEnvironment.isApkDebugable() && BRIDGE_LOG_SWITCH) { + mLodBuilder.append("[WXBridgeManager] callRenderSuccess >>>> instanceId:").append(instanceId); + WXLogUtils.d(mLodBuilder.substring(0)); + mLodBuilder.setLength(0); + } + + if (mDestroyedInstanceId != null && mDestroyedInstanceId.contains(instanceId)) { + return IWXBridge.DESTROY_INSTANCE; + } + + try { + WXSDKInstance instance = WXSDKManager.getInstance().getSDKInstance(instanceId); + if (instance != null) { + GraphicActionRenderSuccess action = new GraphicActionRenderSuccess(instanceId); + WXSDKManager.getInstance().getWXRenderManager().postGraphicAction(instanceId, action); + } + } catch (Exception e) { + WXLogUtils.e("[WXBridgeManager] callRenderSuccess exception: ", e); + WXExceptionUtils.commitCriticalExceptionRT(instanceId, + WXErrorCode.WX_KEY_EXCEPTION_INVOKE, "callCreateFinish", + WXLogUtils.getStackTrace(e), null); + } + + return IWXBridge.INSTANCE_RENDERING; + } + public ContentBoxMeasurement getMeasurementFunc(String instanceId, long renderObjectPtr) { ContentBoxMeasurement contentBoxMeasurement = null; WXSDKInstance instance = WXSDKManager.getInstance().getSDKInstance(instanceId); diff --git a/android/sdk/src/main/java/com/taobao/weex/common/IWXBridge.java b/android/sdk/src/main/java/com/taobao/weex/common/IWXBridge.java index 0207d86a25..1836808eb9 100644 --- a/android/sdk/src/main/java/com/taobao/weex/common/IWXBridge.java +++ b/android/sdk/src/main/java/com/taobao/weex/common/IWXBridge.java @@ -150,6 +150,8 @@ int callUpdateAttrs(String instanceId, String ref, int callCreateFinish(String instanceId); + int callRenderSuccess(String instanceId); + int callAppendTreeCreateFinish(String instanceId, String ref); int callHasTransitionPros(String instanceId, String ref, HashMap styles); diff --git a/android/sdk/src/main/java/com/taobao/weex/ui/action/GraphicActionCreateFinish.java b/android/sdk/src/main/java/com/taobao/weex/ui/action/GraphicActionCreateFinish.java index 2b43eb1350..3e079588b9 100644 --- a/android/sdk/src/main/java/com/taobao/weex/ui/action/GraphicActionCreateFinish.java +++ b/android/sdk/src/main/java/com/taobao/weex/ui/action/GraphicActionCreateFinish.java @@ -65,6 +65,5 @@ public void executeAction() { if (instance.getRenderStrategy() == WXRenderStrategy.APPEND_ONCE) { instance.onCreateFinish(); } - instance.onRenderSuccess(mLayoutWidth, mLayoutHeight); } } diff --git a/android/sdk/src/main/java/com/taobao/weex/ui/action/GraphicActionRenderSuccess.java b/android/sdk/src/main/java/com/taobao/weex/ui/action/GraphicActionRenderSuccess.java new file mode 100644 index 0000000000..32a979113c --- /dev/null +++ b/android/sdk/src/main/java/com/taobao/weex/ui/action/GraphicActionRenderSuccess.java @@ -0,0 +1,55 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package com.taobao.weex.ui.action; + +import com.taobao.weex.WXSDKInstance; +import com.taobao.weex.WXSDKManager; +import com.taobao.weex.ui.component.WXComponent; + +public class GraphicActionRenderSuccess extends BasicGraphicAction { + + private int mLayoutWidth; + private int mLayoutHeight; + + public GraphicActionRenderSuccess(String pageId) { + super(pageId, ""); + final WXSDKInstance instance = WXSDKManager.getInstance() + .getWXRenderManager().getWXSDKInstance(pageId); + if (instance == null) { + return; + } + WXComponent component = instance.getRootComponent(); + if (null != component) { + this.mLayoutWidth = (int) component.getLayoutWidth(); + this.mLayoutHeight = (int) component.getLayoutHeight(); + } + } + + @Override + public void executeAction() { + final WXSDKInstance instance = WXSDKManager.getInstance() + .getWXRenderManager().getWXSDKInstance(getPageId()); + if (instance == null || instance.getContext() == null) { + return; + } + + instance.onRenderSuccess(mLayoutWidth, mLayoutHeight); + } + +} \ No newline at end of file diff --git a/weex_core/Source/CMakeLists.txt b/weex_core/Source/CMakeLists.txt index a63d430599..4edbc10908 100644 --- a/weex_core/Source/CMakeLists.txt +++ b/weex_core/Source/CMakeLists.txt @@ -39,6 +39,7 @@ set(COMMON_SRCS ./core/render/action/render_action_layout.cpp ./core/render/action/render_action_update_attr.cpp ./core/render/action/render_action_update_style.cpp + ./core/render/action/render_action_render_success.cpp ./core/layout/layout.cpp ./core/layout/style.cpp @@ -111,4 +112,4 @@ endif (ANDROID) add_library(${WEEXCORE_LIBRARY_NAME} SHARED ${FINAL_ADD_LIBRARY}) target_include_directories(${WEEXCORE_LIBRARY_NAME} PUBLIC .) -target_link_libraries(${WEEXCORE_LIBRARY_NAME} ${FINAL_TARGET_LINK_LIBRARIES}) \ No newline at end of file +target_link_libraries(${WEEXCORE_LIBRARY_NAME} ${FINAL_TARGET_LINK_LIBRARIES}) diff --git a/weex_core/Source/android/bridge/impl/bridge_impl_android.cpp b/weex_core/Source/android/bridge/impl/bridge_impl_android.cpp index 4d2c1f54bc..7f14389d06 100644 --- a/weex_core/Source/android/bridge/impl/bridge_impl_android.cpp +++ b/weex_core/Source/android/bridge/impl/bridge_impl_android.cpp @@ -48,6 +48,7 @@ static jmethodID jCallHasTransitionProsMethodId; static jmethodID jCallUpdateAttrsMethodId; static jmethodID jCallLayoutMethodId; static jmethodID jCallCreateFinishMethodId; +static jmethodID jCallRenderSuccessMethodId; static jmethodID jCallAppendTreeCreateFinishMethodId; static jmethodID jCallGetMeasurementMethodId; @@ -788,6 +789,31 @@ namespace WeexCore { return flag; } + int Bridge_Impl_Android::callRenderSuccess(const char* pageId) { + + RenderPage *page = RenderManager::GetInstance()->GetPage(pageId); + int64_t startTime = getCurrentTime(); + + JNIEnv *env = getJNIEnv(); + + jstring jPageId = getKeyFromCache(env, pageId); + + if (jCallRenderSuccessMethodId == NULL) + jCallRenderSuccessMethodId = env->GetMethodID(jBridgeClazz, + "callRenderSuccess", + "(Ljava/lang/String;)I"); + + int flag = env->CallIntMethod(jThis, jCallRenderSuccessMethodId, jPageId); + + if (flag == -1) { + LOGE("instance destroy JFM must stop callRenderSuccess"); + } + + if (page != nullptr) + page->CallBridgeTime(getCurrentTime() - startTime); + return flag; + } + int Bridge_Impl_Android::callAppendTreeCreateFinish(const char *pageId, const char *ref) { RenderPage *page = RenderManager::GetInstance()->GetPage(pageId); diff --git a/weex_core/Source/android/bridge/impl/bridge_impl_android.h b/weex_core/Source/android/bridge/impl/bridge_impl_android.h index 825c47cefa..22bee0ffa3 100644 --- a/weex_core/Source/android/bridge/impl/bridge_impl_android.h +++ b/weex_core/Source/android/bridge/impl/bridge_impl_android.h @@ -123,6 +123,8 @@ namespace WeexCore { int callCreateFinish(const char* pageId); + int callRenderSuccess(const char* pageId); + int callAppendTreeCreateFinish(const char* pageId, const char* ref); int callHasTransitionPros(const char* pageId, const char* ref, diff --git a/weex_core/Source/core/bridge/bridge.h b/weex_core/Source/core/bridge/bridge.h index 5aed44617b..e86b60c664 100644 --- a/weex_core/Source/core/bridge/bridge.h +++ b/weex_core/Source/core/bridge/bridge.h @@ -93,6 +93,8 @@ namespace WeexCore { virtual int callCreateFinish(const char* pageId) = 0; + virtual int callRenderSuccess(const char* pageId) = 0; + virtual int callRemoveElement(const char* pageId, const char* ref) = 0; virtual int callMoveElement(const char* pageId, const char* ref, const char* parentRef, int index) = 0; diff --git a/weex_core/Source/core/render/action/render_action_render_success.cpp b/weex_core/Source/core/render/action/render_action_render_success.cpp new file mode 100644 index 0000000000..204f891883 --- /dev/null +++ b/weex_core/Source/core/render/action/render_action_render_success.cpp @@ -0,0 +1,31 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include "core/render/action/render_action_render_success.h" +#include "core/manager/weex_core_manager.h" + +namespace WeexCore { +RenderActionRenderSuccess::RenderActionRenderSuccess(const std::string& page_id) + : page_id_(page_id) {} + +void RenderActionRenderSuccess::ExecuteAction() { + WeexCoreManager::getInstance()->getPlatformBridge()->callRenderSuccess( + page_id_.c_str()); +} +} // namespace WeexCore diff --git a/weex_core/Source/core/render/action/render_action_render_success.h b/weex_core/Source/core/render/action/render_action_render_success.h new file mode 100644 index 0000000000..28ef300fd9 --- /dev/null +++ b/weex_core/Source/core/render/action/render_action_render_success.h @@ -0,0 +1,38 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef CORE_RENDER_ACTION_RENDER_ACTION_RENDER_SUCCESS_H +#define CORE_RENDER_ACTION_RENDER_ACTION_RENDER_SUCCESS_H + +#include +#include "core/render/action/render_action_interface.h" + +namespace WeexCore { +class RenderActionRenderSuccess : public RenderAction { + public: + explicit RenderActionRenderSuccess(const std::string &page_id); + + void ExecuteAction(); + + public: + std::string page_id_; +}; +} // namespace WeexCore + +#endif // CORE_RENDER_ACTION_RENDER_ACTION_RENDER_SUCCESS_H diff --git a/weex_core/Source/core/render/page/render_page.cpp b/weex_core/Source/core/render/page/render_page.cpp index 4c6f25face..49e0c0e2ab 100644 --- a/weex_core/Source/core/render/page/render_page.cpp +++ b/weex_core/Source/core/render/page/render_page.cpp @@ -16,9 +16,9 @@ * specific language governing permissions and limitations * under the License. */ +#include "core/render/page/render_page.h" #include "base/TimeUtils.h" #include "base/ViewUtils.h" -#include "core/render/page/render_page.h" #include "core/config/core_environment.h" #include "core/css/constants_value.h" #include "core/layout/layout.h" @@ -33,6 +33,7 @@ #include "core/render/action/render_action_move_element.h" #include "core/render/action/render_action_remove_element.h" #include "core/render/action/render_action_remove_event.h" +#include "core/render/action/render_action_render_success.h" #include "core/render/action/render_action_update_attr.h" #include "core/render/action/render_action_update_style.h" #include "core/render/manager/render_manager.h" @@ -372,7 +373,8 @@ bool RenderPage::RemoveEvent(const std::string &ref, const std::string &event) { render->RemoveEvent(event); - RenderAction *action = new RenderActionRemoveEvent(this->page_id_, ref, event); + RenderAction *action = + new RenderActionRemoveEvent(this->page_id_, ref, event); PostRenderAction(action); return true; } @@ -383,14 +385,22 @@ bool RenderPage::CreateFinish() { } Batch(); SendCreateFinishAction(); + // RenderSuccess means the Dom created after executing script finishes layout + // and render, it will be trigger even though body not yet attaches to parent. + LayoutInner(); + SendRenderSuccessAction(); return true; } +void RenderPage::LayoutInner() { + CalculateLayout(); + this->need_layout_.store(false); + set_is_dirty(false); +} + void RenderPage::LayoutImmediately() { if (is_dirty() && kUseVSync) { - CalculateLayout(); - this->need_layout_.store(false); - set_is_dirty(false); + LayoutInner(); } } @@ -556,6 +566,11 @@ void RenderPage::SendCreateFinishAction() { PostRenderAction(action); } +void RenderPage::SendRenderSuccessAction() { + RenderAction *action = new RenderActionRenderSuccess(page_id()); + PostRenderAction(action); +} + void RenderPage::SendAppendTreeCreateFinish(const std::string &ref) { RenderAction *action = new RenderActionAppendTreeCreateFinish(page_id(), ref); PostRenderAction(action); @@ -592,9 +607,7 @@ std::vector RenderPage::PrintRenderSuccessLog() { void RenderPage::Batch() { if ((kUseVSync && this->need_layout_.load()) || !kUseVSync) { - CalculateLayout(); - this->need_layout_.store(false); - set_is_dirty(false); + LayoutInner(); } } diff --git a/weex_core/Source/core/render/page/render_page.h b/weex_core/Source/core/render/page/render_page.h index e6803d1cd4..235ec17dea 100644 --- a/weex_core/Source/core/render/page/render_page.h +++ b/weex_core/Source/core/render/page/render_page.h @@ -68,12 +68,15 @@ class RenderPage { void SendCreateFinishAction(); + void SendRenderSuccessAction(); + void SendAppendTreeCreateFinish(const std::string &ref); void PostRenderAction(RenderAction *action); - public: + void LayoutInner(); + public: explicit RenderPage(std::string page_id); ~RenderPage(); @@ -139,8 +142,7 @@ class RenderPage { void OnRenderPageClose(); -public: - + public: inline std::string page_id() { return this->page_id_; } inline bool is_dirty() { return this->is_dirty_.load(); }