Análisis del proceso de carga de Android (carga de diseño de setContentView)

Este artículo describe principalmente cómo onCreatese llama a la aplicación en el método setContentViewpara cargar el diseño. Para aquellos que quieran conocer setContentViewla lógica de ejecución de la aplicación desde el inicio hasta la ejecución , pueden ver el análisis del proceso de carga de Android (desde el inicio de la aplicación hasta la ejecución onCreate) .

Primero mira el setContentViewmétodo

public void setContentView(@LayoutRes int layoutResID) {
    
    
    getWindow().setContentView(layoutResID); //1
    initWindowDecorActionBar(); //2
}

Como se puede ver en el nombre, 1 realizó la carga de la vista, 2 se inicializó ActionBary se visualizó 1, PhoneWindowlos setContentViewmétodos que se pueden rastrear :

public void setContentView(int layoutResID) {
    
    
    if (mContentParent == null) {
    
    
        installDecor(); //1
    } 
    ...
    if (hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
    
    
		...
    } else {
    
    
        mLayoutInflater.inflate(layoutResID, mContentParent); //2
    }
	...
}

Se puede inferir del nombre que 1 realiza algún trabajo de inicialización y 2 es la operación real de cargar dinámicamente la vista. Inflar se carga dinámicamente layoutResIDen la rootvista mContentParent, entonces, mContentParent¿cómo proviene esto y qué tipo de vista es? ** Deje esta pregunta y continúe para ver qué trabajo se ha realizado:

private void installDecor() {
    
    
    if (mDecor == null) {
    
    
        mDecor = generateDecor(-1);
		...
    } else {
    
    
        mDecor.setWindow(this);
    }
    if (mContentParent == null) {
    
    
        mContentParent = generateLayout(mDecor);
        ...
    }
    ...
}

Aquí necesito atención mDecory mContentParentdos objetos.

// This is the top-level view of the window, containing the window decor.
private DecorView mDecor;

Al mirar mDecorla descripción, puede ver que esta es la vista de nivel superior de la ventana. Tenga en cuenta que se DecorViewhereda de FrameLayouty también es unaViewGroup

// This is the view in which the window contents are placed. It is either
// mDecor itself, or a child of mDecor where the contents go.
ViewGroup mContentParent;

Al mirar mContentParentla descripción, puede ver que este es el diseño principal de la vista, que puede ser el diseño de nivel superior en mDecorsí o la subvista a continuación.

protected ViewGroup generateLayout(DecorView decor) {
    
    
    ...
    int layoutResource;
    // System.out.println("Features: 0x" + Integer.toHexString(features));
    if ((features & (1 << FEATURE_SWIPE_TO_DISMISS)) != 0) {
    
    
        layoutResource = R.layout.screen_swipe_dismiss;
        setCloseOnSwipeEnabled(true);
    } else if ((features & ((1 << FEATURE_LEFT_ICON) | (1 << FEATURE_RIGHT_ICON))) != 0) 		{
    
    
		...
    }
    mDecor.onResourcesLoaded(mLayoutInflater, layoutResource);
	...
    return contentParent;
}

Se omite mucha layoutResourcelógica de asignación en el medio , como se puede ver en lo anterior, mDecorllame onResourcesLoadedpara mostrar el diseño de nivel superior, veronResourcesLoaded

void onResourcesLoaded(LayoutInflater inflater, int layoutResource) {
    
    
	...
    mDecorCaptionView = createDecorCaptionView(inflater);
    final View root = inflater.inflate(layoutResource, null);
    if (mDecorCaptionView != null) {
    
    
        if (mDecorCaptionView.getParent() == null) {
    
    
            addView(mDecorCaptionView,
                    new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT));
        }
        mDecorCaptionView.addView(root,
                new ViewGroup.MarginLayoutParams(MATCH_PARENT, MATCH_PARENT));
    } else {
    
    

        // Put it below the color views.
        addView(root, 0, new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT));
    }
    mContentRoot = (ViewGroup) root;
    ...
}

El método para el layoutResourcediseño de carga dinámica , mientras que el obtenido view(raíz) se une a sí mismo ( DecorView), mDecorCaptionViewsolo root, y DecorViewla capa intermedia, esencialmente roota DecorView.
A través de mDecor.onResourcesLoaded(mLayoutInflater, layoutResource), mDecorrenderizando el diseño básico, un diseño de la identificación de la presencia contentdel FrameLayoutcontenedor (el contenedor para ver el área para colocar la apk, generalmente el nuevo proyecto main_acvitityse coloca aquí), como se muestra a continuación
Inserte la descripción de la imagen aquí
después de ejecutar onResourcesLoadedAfter PhoneWindowbuiltcontentParent

//ID_ANDROID_CONTENT: com.android.internal.R.id.content
ViewGroup contentParent = (ViewGroup)findViewById(ID_ANDROID_CONTENT);

En este punto, de repente me di cuenta de que esta contentParentes la vista principal de la vista de apk. Finalmente, generateLayoutla vista principal se devuelve y se asigna amContentParent

mContentParent = generateLayout(mDecor)

El siguiente paso es DecorViewrealizar algunas operaciones de inicialización en algunas de las vistas predeterminadas, por lo que no describiré demasiado, salte installDecory verifique el siguiente punto clave.

mLayoutInflater.inflate(layoutResID, mContentParent)

En este punto, está muy claro. El primer paso installDecores confirmar la vista raíz global, realizar la operación de inicialización y volver a la posición de la vista apk al mismo tiempo mContentParent(ViewGroup). La siguiente tarea es cargar dinámicamente la vista apk ( layoutResID) y vincularlo al correspondiente En el contenedor principal ( mContentParent)

Enlace de referencia: https://www.jianshu.com/p/0f6b4bc86c7b

Supongo que te gusta

Origin blog.csdn.net/weixin_48968045/article/details/114504440
Recomendado
Clasificación