/** * Cause this Activity to be recreated with a new instance. This results * in essentially the same flow as when the Activity is created due to * a configuration change -- the current instance will go through its * lifecycle to {@link #onDestroy} and a new instance then created after it. */
@Override publicvoidonCreate(Bundle savedInstanceState){ // attachBaseContext will only be called from an Activity, so make sure we switch this for // Dialogs, etc mBaseContextAttached = true;
// Our implicit call to applyDayNight() should not recreate until after the Activity is // created applyDayNight(false);
... }
点击进入applyDayNight方法中
1 2 3 4 5 6 7 8 9 10 11 12
privatebooleanapplyDayNight(finalboolean allowRecreation){ if (mIsDestroyed) { if (DEBUG) { Log.d(TAG, "applyDayNight. Skipping because host is destroyed"); } // If we're destroyed, ignore the call returnfalse; }
publicstaticvoidsetDefaultNightMode(@NightModeint mode){ ... switch (mode) { case MODE_NIGHT_NO: case MODE_NIGHT_YES: case MODE_NIGHT_FOLLOW_SYSTEM: case MODE_NIGHT_AUTO_TIME: case MODE_NIGHT_AUTO_BATTERY: if (sDefaultNightMode != mode) { sDefaultNightMode = mode; applyDayNightToActiveDelegates(); } break; default: Log.d(TAG, "setDefaultNightMode() called with an unknown mode"); break; } }
try { //找到START_TAG,否则报异常,说没有入口 advanceToRootNode(parser); final String name = parser.getName();
... //如果是merge标签,查看merge是不是根节点,不然的话抛出异常 if (TAG_MERGE.equals(name)) { if (root == null || !attachToRoot) { thrownew InflateException("<merge /> can be used only with a valid " + "ViewGroup root and attachToRoot=true"); }
rInflate(parser, root, inflaterContext, attrs, false); } else { // Temp is the root view that was found in the xml //获取根节点View final View temp = createViewFromTag(root, name, inflaterContext, attrs); ... //渲染根节点的孩子们 rInflateChildren(parser, temp, attrs, true); ...
//android.view.LayoutInflater View createViewFromTag(View parent, String name, Context context, AttributeSet attrs, boolean ignoreThemeAttr){ if (name.equals("view")) { name = attrs.getAttributeValue(null, "class"); }
// Apply a theme wrapper, if allowed and one is specified. if (!ignoreThemeAttr) { final TypedArray ta = context.obtainStyledAttributes(attrs, ATTRS_THEME); finalint themeResId = ta.getResourceId(0, 0); if (themeResId != 0) { context = new ContextThemeWrapper(context, themeResId); } ta.recycle(); }
if (constructor == null) { // Class not found in the cache, see if it's real, and try to add it clazz = Class.forName(prefix != null ? (prefix + name) : name, false, mContext.getClassLoader()).asSubclass(View.class);
if (mFilter != null && clazz != null) { boolean allowed = mFilter.onLoadClass(clazz); if (!allowed) { failNotAllowed(name, prefix, viewContext, attrs); } } constructor = clazz.getConstructor(mConstructorSignature); constructor.setAccessible(true); sConstructorMap.put(name, constructor); } else { // If we have a filter, apply it to cached constructor if (mFilter != null) { // Have we seen this name before? Boolean allowedState = mFilterMap.get(name); if (allowedState == null) { // New class -- remember whether it is allowed clazz = Class.forName(prefix != null ? (prefix + name) : name, false, mContext.getClassLoader()).asSubclass(View.class);
//androidx.appcompat.app.AppCompatDelegateImpl @Override publicvoidinstallViewFactory(){ LayoutInflater layoutInflater = LayoutInflater.from(mContext); if (layoutInflater.getFactory() == null) { LayoutInflaterCompat.setFactory2(layoutInflater, this); } else { if (!(layoutInflater.getFactory2() instanceof AppCompatDelegateImpl)) { Log.i(TAG, "The Activity's LayoutInflater already has a Factory installed" + " so we can not install AppCompat's"); } } }
@Override public View createView(View parent, final String name, @NonNull Context context, @NonNull AttributeSet attrs){ ... mAppCompatViewInflater = new AppCompatViewInflater(); ... return mAppCompatViewInflater.createView(parent, name, context, attrs, inheritContext, IS_PRE_LOLLIPOP, /* Only read android:theme pre-L (L+ handles this anyway) */ true, /* Read read app:theme as a fallback at all times for legacy reasons */ VectorEnabledTintResources.shouldBeUsed() /* Only tint wrap the context if enabled */ ); }
final View createView(View parent, final String name, @NonNull Context context, @NonNull AttributeSet attrs, boolean inheritContext, boolean readAndroidTheme, boolean readAppTheme, boolean wrapContext){ ... switch (name) { case"TextView": view = createTextView(context, attrs); verifyNotNull(view, name); break; ... default: // The fallback that allows extending class to take over view inflation // for other tags. Note that we don't check that the result is not-null. // That allows the custom inflater path to fall back on the default one // later in this method. view = createView(context, name, attrs); } ... return view; }
//androidx.appcompat.app.AppCompatDelegateImpl @Override publicvoidinstallViewFactory(){ LayoutInflater layoutInflater = LayoutInflater.from(mContext); if (layoutInflater.getFactory() == null) { LayoutInflaterCompat.setFactory2(layoutInflater, this); } else { if (!(layoutInflater.getFactory2() instanceof AppCompatDelegateImpl)) { Log.i(TAG, "The Activity's LayoutInflater already has a Factory installed" + " so we can not install AppCompat's"); } } }