Análise de código-fonte de tags de mesclagem para reduzir o segredo da hierarquia de layout (Android Q)

Análise de código-fonte de tags de mesclagem para reduzir o segredo da hierarquia de layout (Android Q)


Estou em "Otimização do desempenho de renderização do Android - tudo o que você precisa saber! " Descrito no artigo também, as tags de mesclagem usadas para reduzir os níveis da árvore de visualização para otimizar o layout do Android.

Usamos a tag de mesclagem no layout para reduzir níveis desnecessários.

cenas a serem usadas

A tag de mesclagem pode otimizar o nível de layout, então quais são seus principais cenários de uso?

  1. O uso mais comum de mesclar é com a tag de inclusão. Dessa forma, quando o layout for reutilizado, o aninhamento de layout redundante não será adicionado e o problema causado apenas pela tag de inclusão será resolvido.
  2. Além disso, ao personalizar a Visualização combinada (por exemplo, herdar de FrameLayout, LinearLayout, etc.), geralmente criamos um layout personalizado e o adicionamos à Visualização personalizada por meio do id do índice. Neste momento, se a tag de mesclagem não for usado, será invisível. Adicionará um nível de aninhamento.

Por exemplo, personalizamos um container View, o nome da classe é TestLayout, herdado de LinearLayout, o layout de preenchimento deste controle personalizado pode usar a tag de mesclagem.

<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"
       android:layout_width="match_parent"
       android:layout_height="match_parent">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>
</merge>

TestLayout herda de LinearLayout, portanto é um LinearLayout em si. Se modificarmos a mesclagem no layout para LinearLayout, haverá 2 aninhamentos LinearLayout, um dos quais é redundante.

Princípio da tag de mesclagem e análise do código-fonte

Então, qual é o princípio de reduzir o nível da tag de mesclagem?

Para conhecer seu princípio, a forma mais direta é verificar o código-fonte do Android. A seguir, vamos analisar seu princípio de implementação por meio do código-fonte.

Ao ler a análise no artigo anterior "Explicação detalhada do código-fonte da visualização gerada do layout do Android Q" , pode-se ver que o objeto da visualização gerado pelo layout do Android é processado por meio do serviço LayoutInflater e o método inflate do LayoutInflater é responsável por analisar o layout e gerar objetos View. O processamento da tag de mesclagem está incluído neste processo. Vejamos o método inflate de LayoutInflater.

O método inflate de LayoutInflater

    public View inflate(XmlPullParser parser, @Nullable ViewGroup root, boolean attachToRoot) {
        synchronized (mConstructorArgs) {
            ……
            final AttributeSet attrs = Xml.asAttributeSet(parser);
            ……
            try {
                ……
                //如果根标签是 merge 标签
                if (TAG_MERGE.equals(name)) {
                    //如果根节点是 merge,并且 root 是 null 或者 attachToRoot == false,则抛出异常。
                    if (root == null || !attachToRoot) {
                        throw new InflateException("<merge /> can be used only with a valid "
                                + "ViewGroup root and attachToRoot=true");
                    }
                    //遍历布局并生成View
                    rInflate(parser, root, inflaterContext, attrs, false);
                } else {
                    //非 merge 跟标签,则创建根标签所代表的 View 对象。
                    final View temp = createViewFromTag(root, name, inflaterContext, attrs);
                    ViewGroup.LayoutParams params = null;
                    if (root != null) {
                        if (DEBUG) {
                            System.out.println("Creating params from root: " +
                                    root);
                        }
                        //获取根标签 View 对象的视图属性,这里会使用根标签所设置的属性来生成属性对象。
                        params = root.generateLayoutParams(attrs);
                        if (!attachToRoot) {
                            //对根标签设置它的属性
                            temp.setLayoutParams(params);
                        }
                    }
                    ……

                    //以根标签对象为根,递归遍历它的 xml 子视图。
                    rInflateChildren(parser, temp, attrs, true);
                    ……
                }
            }
        }
    }

Para o arquivo de layout com a tag de mesclagem como a tag raiz:

  1. Quando o arquivo de layout da tag de mesclagem é gerado como uma visualização, a raiz deve existir e attachToRoot deve ser verdadeiro, caso contrário, uma InflateException será lançada.
  2. Em seguida, chame o método rInflate para percorrer os sub-rótulos no layout e gerar a visualização.
  3. Aqui, root (a visão pai do arquivo de layout na árvore de visão) e attrs são passados ​​para o método rInflate para criar uma subvisualização do arquivo de layout.

Para arquivos de layout com uma tag não mesclada como a tag raiz:

  1. Crie o objeto View representado pelo rótulo raiz. Isso não é criado na tag de mesclagem, porque mesclagem não é um componente de visualização.
  2. Obtenha as propriedades de visualização do objeto Visualização do rótulo raiz, aqui irá usar as propriedades definidas pelo rótulo raiz para gerar o objeto de propriedade e, em seguida, definir suas propriedades no rótulo raiz. Isso também não é executado durante a tag de mesclagem, portanto, os atributos definidos na tag de mesclagem não terão efeito.
  3. Pegue o objeto de tag raiz como raiz e percorra suas subvisualizações xml recursivamente. Ao mesclar a tag, ele toma a raiz como raiz (como um parâmetro) para percorrer as submarcas da tag de mesclagem. Este é o segredo por trás da tag de mesclagem!

Método RInflate de LayoutInflater

    void rInflate(XmlPullParser parser, View parent, Context context
            AttributeSet attrs, boolean finishInflate) throws XmlPullParserException, IOException {
        ……
        while (((type = parser.next()) != XmlPullParser.END_TAG ||
                parser.getDepth() > depth) && type != XmlPullParser.END_DOCUMENT) {
            ……
            final String name = parser.getName();

            if (TAG_REQUEST_FOCUS.equals(name)) {
                ……
            } 
            …… ……
            } else if (TAG_MERGE.equals(name)) {
                throw new InflateException("<merge /> must be the root element");
            } else {
                final View view = createViewFromTag(parent, name, context, attrs);
                final ViewGroup viewGroup = (ViewGroup) parent;
                final ViewGroup.LayoutParams params = viewGroup.generateLayoutParams(attrs);
                rInflateChildren(parser, view, attrs, true);
                viewGroup.addView(view, params);
            }
        }
        ……
    }

O objetivo deste método é percorrer e criar o objeto de componente View representado pela subtag da tag raiz no arquivo de layout xml.

  1. O método rInflate analisa recursivamente o conteúdo do arquivo de layout xml, cria uma visualização e a adiciona ao pai.
  2. Observe aqui que a tag de mesclagem deve ser o nó raiz do arquivo de layout!

Bem, aqui, já sabemos o segredo da tag de mesclagem.

Resumindo


Vamos resumir:

  1. A tag de mesclagem pode ser usada para reduzir o nível da árvore de visualização para otimizar o layout do Android.

  2. O objeto de exibição gerado pelo layout Android é processado por meio do serviço LayoutInflater. O método inflate de LayoutInflater é responsável por analisar o layout e gerar o objeto Exibir.

  3. Ao usar a tag de mesclagem, a tag de mesclagem deve ser o nó raiz do arquivo de layout!

  4. Quando o arquivo de layout da tag de mesclagem é gerado como uma visualização, a raiz deve existir e attachToRoot deve ser verdadeiro, caso contrário, uma InflateException será lançada.

  5. Os atributos definidos na tag de mesclagem são inválidos!

  6. Ao analisar o arquivo de layout, em circunstâncias normais, o objeto de tag raiz é usado como raiz e suas subvisualizações xml são percorridas recursivamente; ao usar a tag de mesclagem, a raiz é a raiz (como um parâmetro) e passada para o método rInflate para criar uma subvisualização. Este é o segredo por trás da tag de mesclagem!


PS: Para mais artigos de análise, verifique a série de artigos -> coluna "Análise dos princípios básicos do Android" .
PS: Para mais artigos de análise, verifique a série de artigos -> coluna "Análise dos princípios básicos do Android" .
PS: Para mais artigos de análise, verifique a série de artigos -> coluna "Análise dos princípios básicos do Android" .

Acho que você gosta

Origin blog.csdn.net/u011578734/article/details/111494896
Recomendado
Clasificación