Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 31a00a3a authored by Seigo Nonaka's avatar Seigo Nonaka Committed by Android (Google) Code Review
Browse files

Merge "Fix ActivityLeak through text reference" into main

parents db211314 19bd5bcc
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -622,7 +622,7 @@ public class DynamicLayout extends Layout {
            sBuilder = null;
        }

        if (reflowed == null) {
        if (b == null) {
            b = StaticLayout.Builder.obtain(text, where, where + after, getPaint(), getWidth());
        }

@@ -641,7 +641,7 @@ public class DynamicLayout extends Layout {
                .setAddLastLineLineSpacing(!islast)
                .setIncludePad(false);

        reflowed = b.regenerate(true /* trackpadding */, reflowed);
        reflowed = b.buildPartialStaticLayoutForDynamicLayout(true /* trackpadding */, reflowed);
        int n = reflowed.getLineCount();
        // If the new layout has a blank line at the end, but it is not
        // the very end of the buffer, then we already have a line that
+48 −5
Original line number Diff line number Diff line
@@ -437,14 +437,26 @@ public class StaticLayout extends Layout {
            return result;
        }

        /* package */ @NonNull StaticLayout regenerate(boolean trackpadding, StaticLayout recycle) {
        /**
         * DO NOT USE THIS METHOD OTHER THAN DynamicLayout.
         *
         * This class generates a very weird StaticLayout only for getting a result of line break.
         * Since DynamicLayout keeps StaticLayout reference in the static context for object
         * recycling but keeping text reference in static context will end up with leaking Context
         * due to TextWatcher via TextView.
         *
         * So, this is a dirty work around that creating StaticLayout without passing text reference
         * to the super constructor, but calculating the text layout by calling generate function
         * directly.
         */
        /* package */ @NonNull StaticLayout buildPartialStaticLayoutForDynamicLayout(
                boolean trackpadding, StaticLayout recycle) {
            if (recycle == null) {
                return new StaticLayout(this, trackpadding, COLUMNS_ELLIPSIZE);
            } else {
                recycle = new StaticLayout();
            }
            recycle.generate(this, mIncludePad, trackpadding);
            return recycle;
        }
        }

        private CharSequence mText;
        private int mStart;
@@ -473,6 +485,37 @@ public class StaticLayout extends Layout {
        private static final SynchronizedPool<Builder> sPool = new SynchronizedPool<>(3);
    }

    /**
     * DO NOT USE THIS CONSTRUCTOR OTHER THAN FOR DYNAMIC LAYOUT.
     * See Builder#buildPartialStaticLayoutForDynamicLayout for the reason of this constructor.
     */
    private StaticLayout() {
        super(
                null,  // text
                null,  // paint
                0,  // width
                null, // alignment
                null, // textDir
                1, // spacing multiplier
                0, // spacing amount
                false, // include font padding
                false, // fallback line spacing
                0,  // ellipsized width
                null, // ellipsize
                1,  // maxLines
                BREAK_STRATEGY_SIMPLE,
                HYPHENATION_FREQUENCY_NONE,
                null,  // leftIndents
                null,  // rightIndents
                JUSTIFICATION_MODE_NONE,
                null  // lineBreakConfig
        );

        mColumns = COLUMNS_ELLIPSIZE;
        mLineDirections = ArrayUtils.newUnpaddedArray(Directions.class, 2);
        mLines  = ArrayUtils.newUnpaddedIntArray(2 * mColumns);
    }

    /**
     * @deprecated Use {@link Builder} instead.
     */