Este artículo describe principalmente cómo onCreate
se llama a la aplicación en el método setContentView
para cargar el diseño. Para aquellos que quieran conocer setContentView
la 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 setContentView
mé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ó ActionBar
y se visualizó 1, PhoneWindow
los setContentView
mé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 layoutResID
en la root
vista 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 mDecor
y mContentParent
dos objetos.
// This is the top-level view of the window, containing the window decor.
private DecorView mDecor;
Al mirar mDecor
la descripción, puede ver que esta es la vista de nivel superior de la ventana. Tenga en cuenta que se DecorView
hereda de FrameLayout
y 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 mContentParent
la descripción, puede ver que este es el diseño principal de la vista, que puede ser el diseño de nivel superior en mDecor
sí 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 layoutResource
lógica de asignación en el medio , como se puede ver en lo anterior, mDecor
llame onResourcesLoaded
para 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 layoutResource
diseño de carga dinámica , mientras que el obtenido view
(raíz) se une a sí mismo ( DecorView
), mDecorCaptionView
solo root
, y DecorView
la capa intermedia, esencialmente root
a DecorView
.
A través de mDecor.onResourcesLoaded(mLayoutInflater, layoutResource)
, mDecor
renderizando el diseño básico, un diseño de la identificación de la presencia content
del FrameLayout
contenedor (el contenedor para ver el área para colocar la apk, generalmente el nuevo proyecto main_acvitity
se coloca aquí), como se muestra a continuación
después de ejecutar onResourcesLoaded
After PhoneWindow
builtcontentParent
//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 contentParent
es la vista principal de la vista de apk. Finalmente, generateLayout
la vista principal se devuelve y se asigna amContentParent
mContentParent = generateLayout(mDecor)
El siguiente paso es DecorView
realizar algunas operaciones de inicialización en algunas de las vistas predeterminadas, por lo que no describiré demasiado, salte installDecor
y verifique el siguiente punto clave.
mLayoutInflater.inflate(layoutResID, mContentParent)
En este punto, está muy claro. El primer paso installDecor
es 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