1. Introduction
Recently prepared to re-learn Android, deepen understanding, quickly form their own knowledge structure system. The first thing to learn is the view section, from custom view to activty hierarchy, to the layout loading process. And so on, I'll read it, and we'll record the loading process of layout.
2. The process of 2.1 activity loading
Setcontentview Tracking in activity Class (good at bookmark)
public void setContentView(@LayoutRes int layoutResID) { getWindow().setContentView(layoutResID); initWindowDecorActionBar(); }
Tracking code, Phonewindow's Setcontentview method:
Image.png
mLayoutInflater.inflate(layoutResId,mContentParent)
As you can see from the code snippet: Layoutresid's parent layout is mcontentparent. So what exactly is Mcontentparent?
We know that Decorview includes Titleview +contentview.
Image.png
Tracking code: Installdescor ():
Image.png
Generatelayout () Method:
Protected ViewGroupGeneratelayout(Decorview Decor) {Apply data from the current theme.Get the style style of the form TypedArray a = Getwindowstyle ();Omit a lot of extraneous codeInflate the window decor.int Layoutresource;int features = Getlocalfeatures ();//populated with the style and feature attribute Layoutresource (is a layout id) View in = Mlayoutinflater.inflate (Lay Outresource, null); //insert top-level layout Decorview Decor.addview (in, new Viewgroup.layoutparams (Match_parent, match_parent)); Mcontentroot = (viewgroup) in; //find our XML file's parent layout contentparent viewgroup contentparent = (viewgroup) Findviewbyid (ID_ Android_content); if (contentparent = null) {throw new runtimeexception ( "window couldn ' t find content container View "); } //omit irrelevant code mdecor.finishchanging (); //returns contentparent and assigns a value to the member variable mcontentparent return contentparent;}
Add a view named Mcontentroot to Decorview. And Mcontentroot contains a mcontentparent with an ID of id_android_content.
After getting the mcontentparent, the layout is loaded into the Decorview according to Mlayoutinflater.inflate (Layoutresid,mcontentparent), Then this view can be seen by us.
Verify:
Image.png
Explains that Mcontentparent is framlayout.
3.AppCompatActivity Loading View Process
@Override public void setContentView(@LayoutRes int layoutResID) { getDelegate().setContentView(layoutResID); }
Getdelegate ():
@NonNull public AppCompatDelegate getDelegate() { if (mDelegate == null) { mDelegate = AppCompatDelegate.create(this, this); } return mDelegate; }
Track the Create () method,
public static AppCompatDelegate create(Activity activity, AppCompatCallback callback) { return create(activity, activity.getWindow(), callback); }
Activity.getwindow () from the above, it must be phonewindow. The question comes, does the activity really get a non-null Phonewindow at this time? It is found that the Phonewindow is initialized when the activity calls the Attach method:
final void attachint ident, Application application, Intent Intent, activityinfo info, Ch Arsequence title, Activity parent, String ID, nonconfigurationinstances lastnonconfigurationinstances, Configuration Config, String referrer, ivoiceinteractor voiceinteractor, Window window, activityconfigcallback Activityconfigcallback) {Attachbasecontext (context); Mfragments.attachhost (null /*parent*/); Mwindow = new Phonewindow (this, window, Activityconfigcallback); Mwindow.setwindowcontrollercallback (this); ...}
Activity.attach is the call in Performlaunchactivity, which is called in Activitythread. So at any time in the activity GetWindow (), can get Phonewindow.
Continue tracking code:
The Create method is called:
PrivateStatic AppcompatdelegateCreate(Context Context, window window, Appcompatcallback callback) {if (Build.VERSION.SDK_INT >=24) {ReturnNew APPCOMPATDELEGATEIMPLN (context, window, callback); }Elseif (Build.VERSION.SDK_INT >= 23) { return new AppCompatDelegateImplV23 (context, window, callback); } else if (Build.VERSION.SDK_INT >= 14) {return new AppCompatDelegateImplV14 (context, window, callback); } else if (Build.VERSION.SDK_INT >= 11) {return new AppCompatDelegateImplV11 (context, window, callback); } else {return new AppCompatDelegateImplV9 (context, window, callback); } }
Setcontentview is overridden in the AppCompatDelegateImplV9 class, which means that it is ultimately called Appcompatdelegateimplv9.setcontentview ();
@Override public void setContentView(int resId) { ensureSubDecor(); ViewGroup contentParent = (ViewGroup) mSubDecor.findViewById(android.R.id.content); contentParent.removeAllViews(); LayoutInflater.from(mContext).inflate(resId, contentParent); mOriginalWindowCallback.onContentChanged(); }
ViewGroup contentParent = (ViewGroup) mSubDecor.findViewById(android.R.id.content);
It is easy to think that Msubdecor is equivalent to the mcontentroot above.
Let's see what Ensuresubdecor wrote:
if (mOverlayActionMode) { subDecor = (ViewGroup) inflater.inflate( R.layout.abc_screen_simple_overlay_action_mode, null); } else { subDecor = (ViewGroup) inflater.inflate(R.layout.abc_screen_simple, null); }
Subdecor is a system-provided viewgroup that has an android inside. The r.id.content layout is identical to the mcontentroot.
Basically the analysis to this end, is also relatively simple.
Android View Layout loading process