Skip to content

Commit

Permalink
fix(android): textNode memory leak
Browse files Browse the repository at this point in the history
  • Loading branch information
iPel authored and zealotchen0 committed Aug 7, 2023
1 parent 55c38b9 commit 4f8c340
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 49 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,8 @@ public class HippyImageSpan extends ImageSpan {
private String mUrl;
private final WeakReference<ImageNode> mImageNodeWeakRefrence;
private int mImageLoadState = STATE_UNLOAD;
private final HippyImageLoader mImageAdapter;
private final HippyEngineContext engineContext;
private final WeakReference<HippyImageLoader> mImageAdapterRef;
private final WeakReference<HippyEngineContext> engineContextRef;
private Drawable mSrcDrawable = null;
private Movie mGifMovie = null;
private Paint mGifPaint = null;
Expand All @@ -89,9 +89,9 @@ public class HippyImageSpan extends ImageSpan {
public HippyImageSpan(Drawable d, String source, ImageNode node,
HippyImageLoader imageAdapter, HippyEngineContext context) {
super(d, source, node.getVerticalAlignment());
engineContext = context;
engineContextRef = new WeakReference<>(context);
mImageNodeWeakRefrence = new WeakReference<>(node);
mImageAdapter = imageAdapter;
mImageAdapterRef = new WeakReference<>(imageAdapter);
mVerticalAlign = node.getVerticalAlign();
mUseLegacy = TextUtils.isEmpty(mVerticalAlign);
mWidth = Math.round(node.getStyleWidth());
Expand Down Expand Up @@ -164,16 +164,17 @@ private void loadImageWithUrl(String url) {
updateBoundsAttribute();
}

if (mImageAdapter != null) {
HippyImageLoader imageAdapter = mImageAdapterRef.get();
if (imageAdapter != null) {
if (shouldUseFetchImageMode(mUrl)) {
final HippyMap props = new HippyMap();
props.pushBoolean(NodeProps.CUSTOM_PROP_ISGIF, false);
props.pushInt(NodeProps.WIDTH, mWidth);
props.pushInt(NodeProps.HEIGHT, mHeight);

doFetchImage(mUrl, props, mImageAdapter);
doFetchImage(mUrl, props, imageAdapter);
} else {
HippyDrawable hippyDrawable = mImageAdapter.getImage(mUrl, null);
HippyDrawable hippyDrawable = imageAdapter.getImage(mUrl, null);
shouldReplaceDrawable(hippyDrawable);
}
}
Expand Down Expand Up @@ -465,7 +466,7 @@ private void sendImageLoadEvent(ImageEvent eventType) {

if (!TextUtils.isEmpty(eventName) && node.isEnableImageEvent(eventType)) {
HippyViewEvent event = new HippyViewEvent(eventName);
event.send(node.getId(), engineContext, null);
event.send(node.getId(), engineContextRef.get(), null);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,31 +18,32 @@
import android.text.TextPaint;
import android.text.style.MetricAffectingSpan;
import com.tencent.mtt.hippy.adapter.font.HippyFontScaleAdapter;
import java.lang.ref.WeakReference;

@SuppressWarnings({"unused"})
public class HippyStyleSpan extends MetricAffectingSpan {

private final int mStyle;
private final int mWeight;
private final String mFontFamily;
private final HippyFontScaleAdapter fontAdapter;
private final WeakReference<HippyFontScaleAdapter> fontAdapterRef;

public HippyStyleSpan(int fontStyle, int fontWeight, String fontFamily,
HippyFontScaleAdapter adapter) {
mStyle = fontStyle;
mWeight = fontWeight;
mFontFamily = fontFamily;
fontAdapter = adapter;
fontAdapterRef = new WeakReference<>(adapter);
}

@Override
public void updateDrawState(TextPaint ds) {
TypeFaceUtil.apply(ds, mStyle, mWeight, mFontFamily, fontAdapter);
TypeFaceUtil.apply(ds, mStyle, mWeight, mFontFamily, fontAdapterRef.get());
}

@Override
public void updateMeasureState(TextPaint paint) {
TypeFaceUtil.apply(paint, mStyle, mWeight, mFontFamily, fontAdapter);
TypeFaceUtil.apply(paint, mStyle, mWeight, mFontFamily, fontAdapterRef.get());
}

public int getStyle() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -477,47 +477,38 @@ public void setBackgroundColor(int backgroundColor) {
mBackgroundColor = backgroundColor;
}

protected HippyFontScaleAdapter mFontScaleAdapter;
protected HippyEngineContext engineContext;
protected HippyImageLoader mImageAdapter;

@Override
public void layoutBefore(HippyEngineContext context) {
super.layoutBefore(context);

engineContext = context;
if (mFontScaleAdapter == null) {
mFontScaleAdapter = context.getGlobalConfigs().getFontScaleAdapter();
}

if (mImageAdapter == null) {
mImageAdapter = context.getGlobalConfigs().getImageLoaderAdapter();
}
HippyFontScaleAdapter fontScaleAdapter = context.getGlobalConfigs().getFontScaleAdapter();
HippyImageLoader imageAdapter = context.getGlobalConfigs().getImageLoaderAdapter();

if (mIsVirtual) {
return;
}

if (mFontScaleAdapter != null && !TextUtils.isEmpty(mText)) {
CharSequence s = mFontScaleAdapter.getEmoticonText(mText, mFontSize);
if (fontScaleAdapter != null && !TextUtils.isEmpty(mText)) {
CharSequence s = fontScaleAdapter.getEmoticonText(mText, mFontSize);
if (s != null) {
mText = s;
}
}

mSpanned = createSpan(mText, true);
mSpanned = createSpan(mText, true, context, fontScaleAdapter, imageAdapter);
}

@SuppressWarnings({"EmptyMethod", "unused"})
protected void createCustomSpan(CharSequence text, Spannable spannableText) {

}

private SpannableStringBuilder createSpan(CharSequence text, boolean useChild) {
private SpannableStringBuilder createSpan(CharSequence text, boolean useChild, HippyEngineContext context,
HippyFontScaleAdapter fontScaleAdapter, HippyImageLoader imageAdapter) {
if (text != null) {
SpannableStringBuilder spannable = new SpannableStringBuilder();
List<SpanOperation> ops = new ArrayList<>();
createSpanOperations(ops, spannable, this, text, useChild);
createSpanOperations(ops, spannable, this, text, useChild, context, fontScaleAdapter, imageAdapter);

for (int i = ops.size() - 1; i >= 0; i--) {
SpanOperation op = ops.get(i);
Expand All @@ -533,7 +524,7 @@ private SpannableStringBuilder createSpan(CharSequence text, boolean useChild) {
}

private void createImageSpanOperation(List<SpanOperation> ops, SpannableStringBuilder sb,
ImageNode imageNode) {
ImageNode imageNode, HippyEngineContext context, HippyImageLoader imageAdapter) {
String url = null;
String defaultSource = null;
HippyMap props = imageNode.getTotalProps();
Expand All @@ -543,9 +534,9 @@ private void createImageSpanOperation(List<SpanOperation> ops, SpannableStringBu
}

Drawable drawable = null;
if (!TextUtils.isEmpty(defaultSource) && mImageAdapter != null) {
if (!TextUtils.isEmpty(defaultSource) && imageAdapter != null) {
assert defaultSource != null;
HippyDrawable hippyDrawable = mImageAdapter.getImage(defaultSource, null);
HippyDrawable hippyDrawable = imageAdapter.getImage(defaultSource, null);
Bitmap bitmap = hippyDrawable.getBitmap();
if (bitmap != null) {
drawable = new BitmapDrawable(bitmap);
Expand All @@ -560,8 +551,7 @@ private void createImageSpanOperation(List<SpanOperation> ops, SpannableStringBu
int height = Math.round(imageNode.getStyleHeight());
drawable.setBounds(0, 0, width, height);

HippyImageSpan imageSpan = new HippyImageSpan(drawable, url, imageNode, mImageAdapter,
engineContext);
HippyImageSpan imageSpan = new HippyImageSpan(drawable, url, imageNode, imageAdapter, context);
imageNode.setImageSpan(imageSpan);

int start = sb.length();
Expand All @@ -577,7 +567,8 @@ private void createImageSpanOperation(List<SpanOperation> ops, SpannableStringBu
}

private void createSpanOperations(List<SpanOperation> ops, SpannableStringBuilder sb,
TextNode textNode, CharSequence text, boolean useChild) {
TextNode textNode, CharSequence text, boolean useChild, HippyEngineContext context,
HippyFontScaleAdapter fontScaleAdapter, HippyImageLoader imageAdapter) {
int start = sb.length();
sb.append(text);
int end = sb.length();
Expand All @@ -602,19 +593,18 @@ private void createSpanOperations(List<SpanOperation> ops, SpannableStringBuilde
if (textNode.mFontSize != UNSET) {
int fontSize = textNode.mFontSize;

if (textNode.mFontScaleAdapter != null && textNode.mEnableScale) {
fontSize = (int) (fontSize * textNode.mFontScaleAdapter.getFontScale());
if (fontScaleAdapter != null && textNode.mEnableScale) {
fontSize = (int) (fontSize * fontScaleAdapter.getFontScale());
}
ops.add(new SpanOperation(start, end, new AbsoluteSizeSpan(fontSize)));
}
String fontFamily = textNode.mFontFamily;
if (fontFamily == null && mFontScaleAdapter != null) {
fontFamily = mFontScaleAdapter.getCustomDefaultFontFamily();
if (fontFamily == null && fontScaleAdapter != null) {
fontFamily = fontScaleAdapter.getCustomDefaultFontFamily();
}
if (textNode.mFontStyle != UNSET || textNode.mFontWeight != UNSET || fontFamily != null) {
ops.add(new SpanOperation(start, end,
new HippyStyleSpan(textNode.mFontStyle, textNode.mFontWeight, fontFamily,
mFontScaleAdapter)));
new HippyStyleSpan(textNode.mFontStyle, textNode.mFontWeight, fontFamily, fontScaleAdapter)));
}
if (textNode.mIsUnderlineTextDecorationSet) {
ops.add(new SpanOperation(start, end, new UnderlineSpan()));
Expand All @@ -632,8 +622,8 @@ private void createSpanOperations(List<SpanOperation> ops, SpannableStringBuilde
&& mLineSpacingExtra == 0) {
float lineHeight = textNode.mLineHeight;

if (textNode.mFontScaleAdapter != null && textNode.mEnableScale) {
lineHeight = (lineHeight * textNode.mFontScaleAdapter.getFontScale());
if (fontScaleAdapter != null && textNode.mEnableScale) {
lineHeight = (lineHeight * fontScaleAdapter.getFontScale());
}
ops.add(new SpanOperation(start, end, new HippyLineHeightSpan(lineHeight)));
}
Expand All @@ -651,16 +641,16 @@ private void createSpanOperations(List<SpanOperation> ops, SpannableStringBuilde
if (domNode instanceof TextNode) {
TextNode tempNode = (TextNode) domNode;
CharSequence tempText = tempNode.mText;
if (mFontScaleAdapter != null && !TextUtils.isEmpty(tempText)) {
CharSequence s = mFontScaleAdapter.getEmoticonText(tempText, tempNode.mFontSize);
if (fontScaleAdapter != null && !TextUtils.isEmpty(tempText)) {
CharSequence s = fontScaleAdapter.getEmoticonText(tempText, tempNode.mFontSize);
if (s != null) {
tempText = s;
}
}
//noinspection ConstantConditions
createSpanOperations(ops, sb, tempNode, tempText, useChild);
createSpanOperations(ops, sb, tempNode, tempText, useChild, context, fontScaleAdapter, imageAdapter);
} else if (domNode instanceof ImageNode) {
createImageSpanOperation(ops, sb, (ImageNode) domNode);
createImageSpanOperation(ops, sb, (ImageNode) domNode, context, imageAdapter);
} else {
throw new RuntimeException(domNode.getViewClass() + "is not support in Text");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,6 @@ public FlexNode() {
protected void finalize() throws Throwable {
try {
nativeFlexNodeFree(mNativeFlexNode);
mFlexNodeStyle = null;
} finally {
super.finalize();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,6 @@ private static Object createFlexValue(float value, int unit) {
protected void finalize() throws Throwable {
try {
nativeFlexNodeStyleFree(mNativePointer);
mNativePointer = 0;
} finally {
super.finalize();
}
Expand Down

0 comments on commit 4f8c340

Please sign in to comment.