1. 程式人生 > >android 4.2 rtlSupport對UI效能的坑

android 4.2 rtlSupport對UI效能的坑

最近在android 4.2上發現APP特別卡頓的問題,通過抓trace發現很多耗時在ViewGroup.resolveRtlPropertiesIfNeeded, View.resolveRtlPropertiesIfNeeded方法

檢視相關程式碼,google4.2開始支援rtl,也就是右向坐right to left佈局(一些很稀有的小語種國家)

發現每次重新mearsure都要對佈局進行resolveRtlPropertiesIfNeeded

通過檢視程式碼,發現4.2上這個功能做得不完善,4.2的程式碼:

    /**
     * @hide
     */
    @Override
    public void resolveRtlPropertiesIfNeeded() {
        super.resolveRtlPropertiesIfNeeded();
        int count = getChildCount();
        for (int i = 0; i < count; i++) {
            final View child = getChildAt(i);
            if (child.isLayoutDirectionInherited()) {
                child.resolveRtlPropertiesIfNeeded();
            }
        }
    }

遞迴呼叫時並沒有判斷是否需要對子view進行遞迴resolveRtlPropertiesIfNeeded。 並且View的預設rtlSupport是inherit,導致每次measure導遊重新遞迴resolveRtlPropertiesIfNeeded

再看看4.3的程式碼:

    /**
     * @hide
     */
    @Override
    public boolean resolveRtlPropertiesIfNeeded() {
        final boolean result = super.resolveRtlPropertiesIfNeeded();
        // We dont need to resolve the children RTL properties if nothing has changed for the parent
        if (result) {
            int count = getChildCount();
            for (int i = 0; i < count; i++) {
                final View child = getChildAt(i);
                if (child.isLayoutDirectionInherited()) {
                    child.resolveRtlPropertiesIfNeeded();
                }
            }
        }
        return result;
    }

由於沒找到4,3的手機實際測試,沒法確定4.3上android是否徹底解決這個問題,但是在5.0以上手機確實沒發現一次measure過程resolveRtlPropertiesIfNeeded遞迴次數特別多。

針對這種情況,如果APP不需要支援右向左的小語種,可以在AndroidMenifest.xml宣告關閉rtlSupport,並在style中宣告layoutDirection為ltr

<applicationandroid:supportsRtl="false"
<style name="xxxx" parent="@android:style/Theme.Light.NoTitleBar"
> <item name="android:layoutDirection" tools:targetApi="jelly_bean_mr1">ltr</item>