diff --git a/framework/android/connector/renderer/native/src/main/cpp/src/native_renderer_jni.cc b/framework/android/connector/renderer/native/src/main/cpp/src/native_renderer_jni.cc index c2933fa222d..28a286e5a56 100644 --- a/framework/android/connector/renderer/native/src/main/cpp/src/native_renderer_jni.cc +++ b/framework/android/connector/renderer/native/src/main/cpp/src/native_renderer_jni.cc @@ -77,7 +77,12 @@ jint CreateNativeRenderManager(JNIEnv* j_env, jobject j_object) { void DestroyNativeRenderManager(JNIEnv* j_env, jobject j_object, jint j_render_manager_id) { auto render_manager_id = footstone::check::checked_numeric_cast(j_render_manager_id); - auto flag = hippy::global_data_holder.Erase(render_manager_id); + std::any render_manager; + auto flag = hippy::global_data_holder.Find(render_manager_id, render_manager); + if (flag) { + std::static_pointer_cast(std::any_cast>(render_manager))->DestroyRenderDelegate(j_env); + } + flag = hippy::global_data_holder.Erase(render_manager_id); FOOTSTONE_DCHECK(flag); } diff --git a/framework/android/connector/renderer/native/src/main/java/com/openhippy/connector/NativeRenderer.java b/framework/android/connector/renderer/native/src/main/java/com/openhippy/connector/NativeRenderer.java index 0040e4d4ebc..e887b1e2b3d 100644 --- a/framework/android/connector/renderer/native/src/main/java/com/openhippy/connector/NativeRenderer.java +++ b/framework/android/connector/renderer/native/src/main/java/com/openhippy/connector/NativeRenderer.java @@ -133,6 +133,7 @@ public void attachToDom(@NonNull Connector domConnector) { @Override public void destroy() { destroyNativeRenderManager(mInstanceId); + mRenderer = null; } @Override diff --git a/framework/examples/android-demo/src/main/java/com/openhippy/example/HippyEngineWrapper.kt b/framework/examples/android-demo/src/main/java/com/openhippy/example/HippyEngineWrapper.kt index 89e62f20489..99660d2dac4 100644 --- a/framework/examples/android-demo/src/main/java/com/openhippy/example/HippyEngineWrapper.kt +++ b/framework/examples/android-demo/src/main/java/com/openhippy/example/HippyEngineWrapper.kt @@ -122,6 +122,7 @@ class HippyEngineWrapper { hippyEngine.destroyModule(hippyRootView) { result, e -> hippyEngine.destroyEngine() } + hippyRootView = null } fun load(context: Context, callback: HippyEngineLoadCallback) { diff --git a/framework/examples/android-demo/src/main/java/com/openhippy/example/PageConfiguration.kt b/framework/examples/android-demo/src/main/java/com/openhippy/example/PageConfiguration.kt index 7e0c4b54747..87fdd43900c 100644 --- a/framework/examples/android-demo/src/main/java/com/openhippy/example/PageConfiguration.kt +++ b/framework/examples/android-demo/src/main/java/com/openhippy/example/PageConfiguration.kt @@ -121,7 +121,9 @@ class PageConfiguration : AppCompatActivity(), View.OnClickListener { } override fun onBackPressed() { - val goBack: () -> Unit = { buildSnapshot { moveTaskToBack(true) } } + val goBack: () -> Unit = { buildSnapshot { + moveTaskToBack(true) + } } hippyEngineWrapper?.apply { if (hippyEngine.onBackPressed(goBack)) { return @@ -140,6 +142,7 @@ class PageConfiguration : AppCompatActivity(), View.OnClickListener { hippyEngineWrapper?.snapshot = bitmap (pageConfigurationContainer as ViewGroup).removeAllViews() runnable.run() + hippyEngineWrapper = null } }) } diff --git a/renderer/native/android/src/main/cpp/include/renderer/native_render_jni.h b/renderer/native/android/src/main/cpp/include/renderer/native_render_jni.h index 2a0670f43da..2abeb3bf21e 100644 --- a/renderer/native/android/src/main/cpp/include/renderer/native_render_jni.h +++ b/renderer/native/android/src/main/cpp/include/renderer/native_render_jni.h @@ -37,10 +37,6 @@ void OnCreateNativeRenderProvider(JNIEnv* j_env, jint j_render_manager_id, jfloat j_density); -void DestroyNativeRenderManager(JNIEnv* j_env, - jobject j_object, - jint j_render_manager_id); - jobject GetNativeRendererInstance(JNIEnv* j_env, jobject j_object, jint j_render_manager_id); diff --git a/renderer/native/android/src/main/cpp/include/renderer/native_render_manager.h b/renderer/native/android/src/main/cpp/include/renderer/native_render_manager.h index 4b4d501e0bc..3663d8cadc4 100644 --- a/renderer/native/android/src/main/cpp/include/renderer/native_render_manager.h +++ b/renderer/native/android/src/main/cpp/include/renderer/native_render_manager.h @@ -69,6 +69,7 @@ class NativeRenderManager : public RenderManager, public std::enable_shared_from return j_render_manager_; } void CreateRenderDelegate(); + void DestroyRenderDelegate(JNIEnv* j_env); void InitDensity(); void CreateRenderNode(std::weak_ptr root_node, std::vector>&& nodes) override; void UpdateRenderNode(std::weak_ptr root_node, std::vector>&& nodes) override; diff --git a/renderer/native/android/src/main/cpp/src/renderer/native_render_jni.cc b/renderer/native/android/src/main/cpp/src/renderer/native_render_jni.cc index 3788ed67035..aae9ee40716 100644 --- a/renderer/native/android/src/main/cpp/src/renderer/native_render_jni.cc +++ b/renderer/native/android/src/main/cpp/src/renderer/native_render_jni.cc @@ -99,14 +99,6 @@ static void JNI_OnUnload(__unused JavaVM* j_vm, __unused void* reserved) { REGISTER_JNI_ONLOAD(JNI_OnLoad) REGISTER_JNI_ONUNLOAD(JNI_OnUnload) -void DestroyNativeRenderManager(JNIEnv* j_env, jobject j_object, jint j_render_manager_id) { - auto& map = NativeRenderManager::PersistentMap(); - bool ret = map.Erase(static_cast(j_render_manager_id)); - if (!ret) { - FOOTSTONE_DLOG(WARNING) << "DestroyNativeRenderManager delete render manager invalid"; - } -} - bool CreateJavaRenderManager(uint32_t id, std::shared_ptr&j_render_manager, std::shared_ptr&render_delegate) { auto instance = JNIEnvironment::GetInstance(); diff --git a/renderer/native/android/src/main/cpp/src/renderer/native_render_manager.cc b/renderer/native/android/src/main/cpp/src/renderer/native_render_manager.cc index 37971081be7..19c7fbb65f6 100644 --- a/renderer/native/android/src/main/cpp/src/renderer/native_render_manager.cc +++ b/renderer/native/android/src/main/cpp/src/renderer/native_render_manager.cc @@ -95,6 +95,23 @@ void NativeRenderManager::CreateRenderDelegate() { NativeRenderManager::GetStyleFilter(j_render_manager_); } +void NativeRenderManager::DestroyRenderDelegate(JNIEnv* j_env) { + jobject j_object = j_render_manager_->GetObj(); + jclass j_class = j_env->GetObjectClass(j_object); + if (!j_class) { + FOOTSTONE_LOG(ERROR) << "CallNativeMethod j_class error"; + return; + } + jmethodID j_method_id = j_env->GetMethodID(j_class, "destroy", "()V"); + if (!j_method_id) { + FOOTSTONE_LOG(ERROR) << "destroy" << " j_method_id error"; + return; + } + j_env->CallVoidMethod(j_object, j_method_id); + JNIEnvironment::ClearJEnvException(j_env); + j_env->DeleteLocalRef(j_class); +} + void NativeRenderManager::InitDensity() { density_ = hippy::GetDensity(j_render_manager_); } diff --git a/renderer/native/android/src/main/java/com/tencent/mtt/hippy/uimanager/ControllerManager.java b/renderer/native/android/src/main/java/com/tencent/mtt/hippy/uimanager/ControllerManager.java index dd53fc307b3..fcf07571b42 100644 --- a/renderer/native/android/src/main/java/com/tencent/mtt/hippy/uimanager/ControllerManager.java +++ b/renderer/native/android/src/main/java/com/tencent/mtt/hippy/uimanager/ControllerManager.java @@ -68,8 +68,6 @@ public class ControllerManager { - @NonNull - private final Renderer mRenderer; @NonNull private final ControllerRegistry mControllerRegistry; @NonNull @@ -79,6 +77,8 @@ public class ControllerManager { @NonNull private final Map> mRecycleViewPools = new HashMap<>(); @Nullable + private Renderer mRenderer; + @Nullable private static List> sDefaultControllers; public ControllerManager(@NonNull Renderer renderer) { @@ -87,14 +87,14 @@ public ControllerManager(@NonNull Renderer renderer) { mControllerUpdateManger = new ControllerUpdateManger<>(renderer); } - @NonNull + @Nullable public RenderManager getRenderManager() { - return ((NativeRender) mRenderer).getRenderManager(); + return mRenderer != null ? ((NativeRender) mRenderer).getRenderManager() : null; } - @NonNull + @Nullable public NativeRender getNativeRender() { - return (NativeRender) mRenderer; + return mRenderer != null ? ((NativeRender) mRenderer) : null; } @NonNull @@ -179,6 +179,8 @@ public HippyCustomPropsController getCustomPropsController() { } public void destroy() { + mControllerRegistry.clear(); + mControllerUpdateManger.clear(); for (Pool pool : mPreCreateViewPools.values()) { pool.clear(); } @@ -193,6 +195,7 @@ public void destroy() { deleteRootView(mControllerRegistry.getRootIdAt(i)); } } + mRenderer = null; } @Nullable @@ -647,15 +650,21 @@ private String getViewOperationExceptionMessage(int pid, View parent, int id, Vi } private void reportRemoveViewException(int pid, View parent, int id, View child) { - NativeRenderException exception = new NativeRenderException(REMOVE_CHILD_VIEW_FAILED_ERR, - getViewOperationExceptionMessage(pid, parent, id, child, "Remove view failed:")); - mRenderer.handleRenderException(exception); + if (mRenderer != null) { + NativeRenderException exception = new NativeRenderException( + REMOVE_CHILD_VIEW_FAILED_ERR, + getViewOperationExceptionMessage(pid, parent, id, child, + "Remove view failed:")); + mRenderer.handleRenderException(exception); + } } private void reportAddViewException(int pid, View parent, int id, View child) { - NativeRenderException exception = new NativeRenderException(ADD_CHILD_VIEW_FAILED_ERR, - getViewOperationExceptionMessage(pid, parent, id, child, - "Add child to parent failed:")); - mRenderer.handleRenderException(exception); + if (mRenderer != null) { + NativeRenderException exception = new NativeRenderException(ADD_CHILD_VIEW_FAILED_ERR, + getViewOperationExceptionMessage(pid, parent, id, child, + "Add child to parent failed:")); + mRenderer.handleRenderException(exception); + } } } diff --git a/renderer/native/android/src/main/java/com/tencent/mtt/hippy/uimanager/ControllerRegistry.java b/renderer/native/android/src/main/java/com/tencent/mtt/hippy/uimanager/ControllerRegistry.java index 88fc073379c..4bea4686dca 100644 --- a/renderer/native/android/src/main/java/com/tencent/mtt/hippy/uimanager/ControllerRegistry.java +++ b/renderer/native/android/src/main/java/com/tencent/mtt/hippy/uimanager/ControllerRegistry.java @@ -41,13 +41,17 @@ public class ControllerRegistry { private final SparseArray mRootViews = new SparseArray<>(); @NonNull private final Map mControllers = new HashMap<>(); - @NonNull - private final Renderer mRenderer; + @Nullable + private Renderer mRenderer; public ControllerRegistry(@NonNull Renderer renderer) { mRenderer = renderer; } + public void clear() { + mRenderer = null; + } + public void addControllerHolder(String name, ControllerHolder controllerHolder) { mControllers.put(name, controllerHolder); } @@ -62,9 +66,11 @@ public ControllerHolder getControllerHolder(String className) { public HippyViewController getViewController(@NonNull String className) { ControllerHolder holder = mControllers.get(className); if (holder == null) { - NativeRenderException exception = new NativeRenderException( - GET_VIEW_CONTROLLER_FAILED_ERR, "Unknown class name=" + className); - mRenderer.handleRenderException(exception); + if (mRenderer != null) { + NativeRenderException exception = new NativeRenderException( + GET_VIEW_CONTROLLER_FAILED_ERR, "Unknown class name=" + className); + mRenderer.handleRenderException(exception); + } return null; } return holder.getViewController(); diff --git a/renderer/native/android/src/main/java/com/tencent/mtt/hippy/uimanager/ControllerUpdateManger.java b/renderer/native/android/src/main/java/com/tencent/mtt/hippy/uimanager/ControllerUpdateManger.java index fc761d660bc..6f503828784 100644 --- a/renderer/native/android/src/main/java/com/tencent/mtt/hippy/uimanager/ControllerUpdateManger.java +++ b/renderer/native/android/src/main/java/com/tencent/mtt/hippy/uimanager/ControllerUpdateManger.java @@ -38,8 +38,10 @@ import com.tencent.renderer.utils.PropertyUtils.PropertyMethodHolder; import com.tencent.renderer.node.RenderNode; +import java.lang.ref.WeakReference; import java.lang.reflect.Method; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Map; @@ -61,8 +63,8 @@ public class ControllerUpdateManger { NodeProps.OPACITY, NodeProps.OVERFLOW }; - @NonNull - private final Renderer mRenderer; + @Nullable + private Renderer mRenderer; @Nullable private ComponentController mComponentController; @Nullable @@ -78,6 +80,10 @@ public ControllerUpdateManger(@NonNull Renderer renderer) { mRenderer = renderer; } + public void clear() { + mRenderer = null; + } + public void setCustomPropsController(T controller) { mCustomPropsController = controller; } @@ -124,9 +130,7 @@ private static void initComponentPropsMap() { sRenderPropsList.add(controllerProps.name()); } } - for (String layoutStyle : sLayoutStyleList) { - sRenderPropsList.add(layoutStyle); - } + Collections.addAll(sRenderPropsList, sLayoutStyleList); } void findViewPropsMethod(Class cls, @@ -177,9 +181,11 @@ private void invokePropMethod(@NonNull Object obj, @NonNull Object arg1, methodHolder.method.invoke(obj, arg1, value); } } catch (Exception exception) { - mRenderer.handleRenderException( - PropertyUtils.makePropertyConvertException(exception, key, - methodHolder.method)); + if (mRenderer != null) { + mRenderer.handleRenderException( + PropertyUtils.makePropertyConvertException(exception, key, + methodHolder.method)); + } } } diff --git a/renderer/native/android/src/main/java/com/tencent/mtt/hippy/uimanager/HippyViewController.java b/renderer/native/android/src/main/java/com/tencent/mtt/hippy/uimanager/HippyViewController.java index 8a584777f46..ba898f1c1f0 100644 --- a/renderer/native/android/src/main/java/com/tencent/mtt/hippy/uimanager/HippyViewController.java +++ b/renderer/native/android/src/main/java/com/tencent/mtt/hippy/uimanager/HippyViewController.java @@ -59,11 +59,11 @@ public abstract class HippyViewController implem private static final double[] sTransformDecompositionArray = new double[16]; private boolean bUserChangeFocus = false; - public View createView(@NonNull View rootView, int id, @NonNull Renderer renderer, + public View createView(@NonNull View rootView, int id, @Nullable Renderer renderer, @NonNull String className, @Nullable Map props) { View view = null; Context context = rootView.getContext(); - Object object = renderer.getCustomViewCreator(); + Object object = renderer != null ? renderer.getCustomViewCreator() : null; if (object instanceof HippyCustomViewCreator) { view = ((HippyCustomViewCreator) object) .createCustomView(className, context, props); diff --git a/renderer/native/android/src/main/java/com/tencent/renderer/NativeRenderProvider.java b/renderer/native/android/src/main/java/com/tencent/renderer/NativeRenderProvider.java index 90081633010..c9b271dc72f 100644 --- a/renderer/native/android/src/main/java/com/tencent/renderer/NativeRenderProvider.java +++ b/renderer/native/android/src/main/java/com/tencent/renderer/NativeRenderProvider.java @@ -28,6 +28,7 @@ import com.tencent.renderer.serialization.Deserializer; import com.tencent.renderer.serialization.Serializer; +import java.lang.ref.WeakReference; import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.List; @@ -40,26 +41,30 @@ */ public class NativeRenderProvider { - @NonNull - private final NativeRenderDelegate mRenderDelegate; @NonNull private final Deserializer mDeserializer; @NonNull private final Serializer mSerializer; + @NonNull + private final WeakReference mRenderDelegateRef; @Nullable private BinaryReader mSafeHeapReader; @Nullable private SafeHeapWriter mSafeHeapWriter; private int mInstanceId; + private final Object mSnapshotsSyncLock = new Object(); public NativeRenderProvider(@NonNull NativeRenderDelegate renderDelegate) { - mRenderDelegate = renderDelegate; + mRenderDelegateRef = new WeakReference<>(renderDelegate); mSerializer = new Serializer(); mDeserializer = new Deserializer(null, new InternalizedStringTable()); } public void setInstanceId(int instanceId) { - NativeRendererManager.addNativeRendererInstance(instanceId, (NativeRender)mRenderDelegate); + // Call set id follows the create native renderer, so RenderDelegate should not be null here. + assert mRenderDelegateRef.get() != null; + NativeRendererManager.addNativeRendererInstance(instanceId, + (NativeRender) (mRenderDelegateRef.get())); mInstanceId = instanceId; } @@ -125,14 +130,17 @@ private ByteBuffer argumentToBytes(@NonNull Object params) throws NativeRenderEx @CalledByNative @SuppressWarnings("unused") public void createNode(int rootId, byte[] buffer) { - // Replay snapshots are executed in the UI thread, which may generate multithreaded problem with - // the create node of the dom thread, so synchronized with native renderer object here. - synchronized(mRenderDelegate) { - try { - final List list = bytesToArgument(ByteBuffer.wrap(buffer)); - mRenderDelegate.createNode(rootId, list); - } catch (NativeRenderException e) { - mRenderDelegate.handleRenderException(e); + NativeRenderDelegate renderDelegate = mRenderDelegateRef.get(); + if (renderDelegate != null) { + // Replay snapshots are executed in the UI thread, which may generate multithreaded problem with + // the create node of the dom thread, so synchronized with lock object here. + synchronized (mSnapshotsSyncLock) { + try { + final List list = bytesToArgument(ByteBuffer.wrap(buffer)); + renderDelegate.createNode(rootId, list); + } catch (NativeRenderException e) { + renderDelegate.handleRenderException(e); + } } } } @@ -146,11 +154,14 @@ public void createNode(int rootId, byte[] buffer) { @CalledByNative @SuppressWarnings("unused") public void updateNode(int rootId, byte[] buffer) { - try { - final List list = bytesToArgument(ByteBuffer.wrap(buffer)); - mRenderDelegate.updateNode(rootId, list); - } catch (NativeRenderException e) { - mRenderDelegate.handleRenderException(e); + NativeRenderDelegate renderDelegate = mRenderDelegateRef.get(); + if (renderDelegate != null) { + try { + final List list = bytesToArgument(ByteBuffer.wrap(buffer)); + renderDelegate.updateNode(rootId, list); + } catch (NativeRenderException e) { + renderDelegate.handleRenderException(e); + } } } @@ -163,10 +174,13 @@ public void updateNode(int rootId, byte[] buffer) { @CalledByNative @SuppressWarnings("unused") public void deleteNode(int rootId, int[] ids) { - try { - mRenderDelegate.deleteNode(rootId, ids); - } catch (NativeRenderException e) { - mRenderDelegate.handleRenderException(e); + NativeRenderDelegate renderDelegate = mRenderDelegateRef.get(); + if (renderDelegate != null) { + try { + renderDelegate.deleteNode(rootId, ids); + } catch (NativeRenderException e) { + renderDelegate.handleRenderException(e); + } } } @@ -174,8 +188,7 @@ public void deleteNode(int rootId, int[] ids) { * Call from native (C++) render manager to move render node * *

- * Move the child node to the new parent node - * + * Move the child node to the new parent node * * @param rootId the root node id * @param ids the node id array list @@ -186,10 +199,13 @@ public void deleteNode(int rootId, int[] ids) { @CalledByNative @SuppressWarnings("unused") public void moveNode(int rootId, int[] ids, int newPid, int oldPid, int insertIndex) { - try { - mRenderDelegate.moveNode(rootId, ids, newPid, oldPid, insertIndex); - } catch (NativeRenderException e) { - mRenderDelegate.handleRenderException(e); + NativeRenderDelegate renderDelegate = mRenderDelegateRef.get(); + if (renderDelegate != null) { + try { + renderDelegate.moveNode(rootId, ids, newPid, oldPid, insertIndex); + } catch (NativeRenderException e) { + renderDelegate.handleRenderException(e); + } } } @@ -197,8 +213,7 @@ public void moveNode(int rootId, int[] ids, int newPid, int oldPid, int insertIn * Call from native (C++) render manager to move render node * *

- * Adjust the order of child nodes under the same parent node - * + * Adjust the order of child nodes under the same parent node * * @param rootId the root node id * @param pid the parent node id @@ -207,11 +222,14 @@ public void moveNode(int rootId, int[] ids, int newPid, int oldPid, int insertIn @CalledByNative @SuppressWarnings("unused") public void moveNode(int rootId, int pid, byte[] buffer) { - try { - final List list = bytesToArgument(ByteBuffer.wrap(buffer)); - mRenderDelegate.moveNode(rootId, pid, list); - } catch (NativeRenderException e) { - mRenderDelegate.handleRenderException(e); + NativeRenderDelegate renderDelegate = mRenderDelegateRef.get(); + if (renderDelegate != null) { + try { + final List list = bytesToArgument(ByteBuffer.wrap(buffer)); + renderDelegate.moveNode(rootId, pid, list); + } catch (NativeRenderException e) { + renderDelegate.handleRenderException(e); + } } } @@ -224,11 +242,14 @@ public void moveNode(int rootId, int pid, byte[] buffer) { @CalledByNative @SuppressWarnings("unused") public void updateLayout(int rootId, byte[] buffer) { - try { - final List list = bytesToArgument(ByteBuffer.wrap(buffer)); - mRenderDelegate.updateLayout(rootId, list); - } catch (NativeRenderException e) { - mRenderDelegate.handleRenderException(e); + NativeRenderDelegate renderDelegate = mRenderDelegateRef.get(); + if (renderDelegate != null) { + try { + final List list = bytesToArgument(ByteBuffer.wrap(buffer)); + renderDelegate.updateLayout(rootId, list); + } catch (NativeRenderException e) { + renderDelegate.handleRenderException(e); + } } } @@ -241,11 +262,14 @@ public void updateLayout(int rootId, byte[] buffer) { @CalledByNative @SuppressWarnings("unused") public void updateEventListener(int rootId, byte[] buffer) { - try { - final List list = bytesToArgument(ByteBuffer.wrap(buffer)); - mRenderDelegate.updateEventListener(rootId, list); - } catch (NativeRenderException e) { - mRenderDelegate.handleRenderException(e); + NativeRenderDelegate renderDelegate = mRenderDelegateRef.get(); + if (renderDelegate != null) { + try { + final List list = bytesToArgument(ByteBuffer.wrap(buffer)); + renderDelegate.updateEventListener(rootId, list); + } catch (NativeRenderException e) { + renderDelegate.handleRenderException(e); + } } } @@ -264,7 +288,11 @@ public void updateEventListener(int rootId, byte[] buffer) { @SuppressWarnings("unused") public long measure(int rootId, int nodeId, float width, int widthMode, float height, int heightMode) { - return mRenderDelegate.measure(rootId, nodeId, width, widthMode, height, heightMode); + NativeRenderDelegate renderDelegate = mRenderDelegateRef.get(); + if (renderDelegate != null) { + return renderDelegate.measure(rootId, nodeId, width, widthMode, height, heightMode); + } + return 0; } /** @@ -280,11 +308,14 @@ public long measure(int rootId, int nodeId, float width, int widthMode, float he @SuppressWarnings("unused") public void callUIFunction(int rootId, int nodeId, long callbackId, String functionName, byte[] buffer) { - try { - final List list = bytesToArgument(ByteBuffer.wrap(buffer)); - mRenderDelegate.callUIFunction(rootId, nodeId, callbackId, functionName, list); - } catch (NativeRenderException e) { - mRenderDelegate.handleRenderException(e); + NativeRenderDelegate renderDelegate = mRenderDelegateRef.get(); + if (renderDelegate != null) { + try { + final List list = bytesToArgument(ByteBuffer.wrap(buffer)); + renderDelegate.callUIFunction(rootId, nodeId, callbackId, functionName, list); + } catch (NativeRenderException e) { + renderDelegate.handleRenderException(e); + } } } @@ -296,10 +327,13 @@ public void callUIFunction(int rootId, int nodeId, long callbackId, String funct @CalledByNative @SuppressWarnings("unused") public void endBatch(int rootId) { - try { - mRenderDelegate.endBatch(rootId); - } catch (NativeRenderException e) { - mRenderDelegate.handleRenderException(e); + NativeRenderDelegate renderDelegate = mRenderDelegateRef.get(); + if (renderDelegate != null) { + try { + renderDelegate.endBatch(rootId); + } catch (NativeRenderException e) { + renderDelegate.handleRenderException(e); + } } } @@ -335,7 +369,10 @@ public void doPromiseCallBack(int result, long callbackId, @NonNull String funct offset += buffer.arrayOffset(); bytes = buffer.array(); } catch (Exception e) { - mRenderDelegate.handleRenderException(e); + NativeRenderDelegate renderDelegate = mRenderDelegateRef.get(); + if (renderDelegate != null) { + renderDelegate.handleRenderException(e); + } return; } } @@ -356,7 +393,10 @@ public void dispatchEvent(int rootId, int nodeId, @NonNull String eventName, offset += buffer.arrayOffset(); bytes = buffer.array(); } catch (Exception e) { - mRenderDelegate.handleRenderException(e); + NativeRenderDelegate renderDelegate = mRenderDelegateRef.get(); + if (renderDelegate != null) { + renderDelegate.handleRenderException(e); + } return; } } @@ -364,15 +404,6 @@ public void dispatchEvent(int rootId, int nodeId, @NonNull String eventName, useBubble); } - /** - * Set screen displayMetrics density to native (C++) render manager. - * - * @param density screen displayMetrics density - * @return the unique id of native (C++) render manager - */ - @SuppressWarnings("JavaJniMissingFunction") - private native void onCreateNativeRenderProvider(int instanceId, float density); - /** * Call back from Android system when size changed, just like horizontal and vertical screen * switching, call this jni interface to invoke dom tree relayout. diff --git a/renderer/native/android/src/main/java/com/tencent/renderer/node/TextVirtualNode.java b/renderer/native/android/src/main/java/com/tencent/renderer/node/TextVirtualNode.java index bfecada97ac..4d434f852c4 100644 --- a/renderer/native/android/src/main/java/com/tencent/renderer/node/TextVirtualNode.java +++ b/renderer/native/android/src/main/java/com/tencent/renderer/node/TextVirtualNode.java @@ -452,7 +452,8 @@ protected Layout createLayout(final float width, final FlexMeasureMode widthMode if (mSpanned == null || mDirty) { mSpanned = createSpan(true); mDirty = false; - } else if (mLayout != null && width >= mLastLayoutWidth && width <= (mLastLayoutWidth + 1)) { + } else if (mLayout != null && width >= (mLastLayoutWidth - 1) + && width <= (mLastLayoutWidth + 1)) { // If the property of text node no change, and the current layout width is equal // to the last measurement result, no need to create layout again. return mLayout; @@ -468,7 +469,7 @@ protected Layout createLayout(final float width, final FlexMeasureMode widthMode } else { float desiredWidth = Layout.getDesiredWidth(mSpanned, textPaint); if (!unconstrainedWidth && (widthMode == FlexMeasureMode.EXACTLY - || desiredWidth > width)) { + || desiredWidth > width)) { desiredWidth = width; } layout = buildStaticLayout(mSpanned, textPaint, (int) Math.ceil(desiredWidth));