創(chuàng)建LayoutInflater對(duì)象,根據(jù)所傳的上下文對(duì)象不同,創(chuàng)建出來(lái)的LayoutInflater對(duì)象也不同,在不同Activity中創(chuàng)建的LayoutInflater對(duì)象也不同,先來(lái)看一下,
Activity中的獲取LayoutInflater對(duì)象及打印的對(duì)象地址LayoutInflater.from(this); com.android.internal.policy.impl.PhoneLayoutInflater@41882b90LayoutInflater.from(getapplication()); com.android.internal.policy.impl.PhoneLayoutInflater@418da098 LayoutInflater.from(getBaseContext()); com.android.internal.policy.impl.PhoneLayoutInflater@41882b40 getSystemService(Context.LAYOUT_INFLATER_SERVICE); com.android.internal.policy.impl.PhoneLayoutInflater@41882b90 getApplication().getSystemService(Context.LAYOUT_INFLATER_SERVICE);com.android.internal.policy.impl.PhoneLayoutInflater@418da098 getBaseContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);com.android.internal.policy.impl.PhoneLayoutInflater@41882b40 getBaseContext(); android.app.ContextImpl@41882338 getApplication().getBaseContext(); android.app.ContextImpl@41870230 另一Activity中的獲取LayoutInflater對(duì)象及打印的對(duì)象地址LayoutInflater.from(this); com.android.internal.policy.impl.PhoneLayoutInflater@4189f2f0LayoutInflater.from(getApplication()); com.android.internal.policy.impl.PhoneLayoutInflater@418da098 LayoutInflater.from(getBaseContext()); com.android.internal.policy.impl.PhoneLayoutInflater@4189f2a0 getSystemService(Context.LAYOUT_INFLATER_SERVICE); com.android.internal.policy.impl.PhoneLayoutInflater@4189f2f0 getApplication().getSystemService(Context.LAYOUT_INFLATER_SERVICE);com.android.internal.policy.impl.PhoneLayoutInflater@418da098 getBaseContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);com.android.internal.policy.impl.PhoneLayoutInflater@4189f2a0 getBaseContext(); android.app.ContextImpl@4189ecd8 getApplication().getBaseContext(); android.app.ContextImpl@41870230根據(jù)LayoutInflate的form方法中的實(shí)現(xiàn),其實(shí)LayoutInflater.from(this);LayoutInflater.from(getApplication());LayoutInflater.from(getBaseContext());和getSystemService(Context.LAYOUT_INFLATER_SERVICE);getApplication().getSystemService(Context.LAYOUT_INFLATER_SERVICE);getBaseContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);其實(shí)是一個(gè)意思,所以他們獲取的對(duì)象都是一樣的,那為什么不同上下文對(duì)象獲取的LayoutInflater對(duì)象也不同呢,因?yàn)椴煌珻ontext對(duì)象中的mBase(ContextImpl)對(duì)象不同,LayoutInflater就是在ContextImpl中創(chuàng)建的,所以創(chuàng)建的對(duì)象不同
下面咱來(lái)看一下LayoutInflater創(chuàng)建過(guò)程,咱們來(lái)跟蹤一下代碼,就拿LayoutInflater.from(this)來(lái)說(shuō),看LayoutInflater中的form()方法
public static LayoutInflater from(Context context) { LayoutInflater LayoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); if (LayoutInflater == null) { throw new AssertionError("LayoutInflater not found."); } return LayoutInflater; }該方法中調(diào)用了Context的getSystemService()方法,因?yàn)閭鞯氖莟his,即是Activity對(duì)象,Activity是也是Context對(duì)象,他們的繼承關(guān)系為:Activity -> ContextThemeWrapper -> ContextWrapper -> Context。所以看Context的子類是否重寫了getSystemService()方法,正好ContextThemeWrapper重寫了,Activity也重寫了,但和LayoutInflater沒(méi)有關(guān)系,所以我們看ContextThemeWrapper中的getSystemService()方法public Object getSystemService(String name) { if (LAYOUT_INFLATER_SERVICE.equals(name)) { if (mInflater == null) { mInflater = LayoutInflater.from(getBaseContext()).cloneInContext(this); } return mInflater; } return getBaseContext().getSystemService(name); }一開(kāi)始的時(shí)候,mInflater肯定是為null,執(zhí)行LayoutInflater.from(getBaseContext())方法,又回到了剛開(kāi)始的LayoutInflater.from()方法,不一樣的是這次上下文的對(duì)象是ContextImpl對(duì)象,為什么是ContextImpl,我們看getBaseContext()方法public Context getBaseContext() { return mBase; }該返回就只返回了mBase,我們看其是在哪里賦值的,是在ContextWrapper類的attachBaseContext方法中賦值的PRotected void attachBaseContext(Context base) { if (mBase != null) { throw new IllegalStateException("Base context already set"); } mBase = base; }該方法又是在哪里調(diào)用的呢,是在Activity的attach方法中調(diào)用的final void attach(Context context, ActivityThread aThread, Instrumentation instr, IBinder token, int ident, Application application, Intent intent, ActivityInfo info, CharSequence title, Activity parent, String id, NonConfigurationInstances lastNonConfigurationInstances, Configuration config, String referrer, IVoiceInteractor voiceInteractor) { attachBaseContext(context); ...... }attach又是在哪里調(diào)用的呢,在ActivityThread中調(diào)用的private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) { ...... if (activity != null) { Context appContext = createBaseContextForActivity(r, activity); CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager()); Configuration config = new Configuration(mCompatConfiguration); if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity " + r.activityInfo.name + " with config " + config); activity.attach(appContext, this, getInstrumentation(), r.token, r.ident, app, r.intent, r.activityInfo, title, r.parent, r.embeddedID, r.lastNonConfigurationInstances, config, r.referrer, r.voiceInteractor); ...... } ......}而appContext又是createBaseContextForActivity(r, activity)方法返回的,private Context createBaseContextForActivity(ActivityClientRecord r, final Activity activity) { ...... ContextImpl appContext = ContextImpl.createActivityContext( this, r.packageInfo, displayId, r.overrideConfig); appContext.setOuterContext(activity); Context baseContext = appContext; final DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance(); String pkgName = SystemProperties.get("debug.second-display.pkg"); if (pkgName != null && !pkgName.isEmpty() && r.packageInfo.mPackageName.contains(pkgName)) { for (int id : dm.getDisplayIds()) { if (id != Display.DEFAULT_DISPLAY) { Display display = dm.getCompatibleDisplay(id, appContext.getDisplayAdjustments(id)); baseContext = appContext.createDisplayContext(display); break; } } } return baseContext; }baseContext又是通過(guò)ContextImpl的createActivityContext()方法獲取的static ContextImpl createActivityContext(ActivityThread mainThread, LoadedApk packageInfo, int displayId, Configuration overrideConfiguration) { if (packageInfo == null) throw new IllegalArgumentException("packageInfo"); return new ContextImpl(null, mainThread, packageInfo, null, null, false, null, overrideConfiguration, displayId); }看到?jīng)],返回的對(duì)象是new ContextImpl出來(lái)的,所以之前的getBaseContext()獲取的就是ContextImpl對(duì)象。所以不同對(duì)象的Context中的ContextImpl對(duì)象就不同,所以創(chuàng)建出來(lái)的LayoutInflater的對(duì)象可能就不同,往下看所以我們?cè)倏碙ayoutInflater.from()中的context.getSystemService(Context.LAYOUT_INFLATER_SERVICE)語(yǔ)句,這個(gè)context就是ContextImpl對(duì)象,看其方法
@Override public Object getSystemService(String name) { return SystemServiceRegistry.getSystemService(this, name); }SystemServiceRegistry的getSystemService方法public static Object getSystemService(ContextImpl ctx, String name) { ServiceFetcher<?> fetcher = SYSTEM_SERVICE_FETCHERS.get(name); return fetcher != null ? fetcher.getService(ctx) : null; }我們?cè)诟M(jìn)getService()static abstract interface ServiceFetcher<T> { T getService(ContextImpl ctx); } static abstract class CachedServiceFetcher<T> implements ServiceFetcher<T> { private final int mCacheIndex; public CachedServiceFetcher() { mCacheIndex = sServiceCacheSize++; } @Override @SuppressWarnings("unchecked") public final T getService(ContextImpl ctx) { final Object[] cache = ctx.mServiceCache; synchronized (cache) { // Fetch or create the service. Object service = cache[mCacheIndex]; if (service == null) { service = createService(ctx); cache[mCacheIndex] = service; } return (T)service; } } public abstract T createService(ContextImpl ctx); }它會(huì)先從cache中獲取,如果沒(méi)有就去創(chuàng)建createService,因?yàn)槠鋵?shí)抽象的,所以看其實(shí)現(xiàn)類registerService(Context.LAYOUT_INFLATER_SERVICE, LayoutInflater.class, new CachedServiceFetcher<LayoutInflater>() { @Override public LayoutInflater createService(ContextImpl ctx) { return new PhoneLayoutInflater(ctx.getOuterContext()); }});到這里終于看到了LayoutInflater 對(duì)象 PhoneLayoutInflater,其實(shí)這還不是LayoutInflater.from(this)的最終對(duì)象,看ContextThemeWrapper 的mInflater = LayoutInflater.from(getBaseContext()).cloneInContext(this);其實(shí)他在得到對(duì)象的時(shí)候又clone了一個(gè)public LayoutInflater cloneInContext(Context newContext) { return new PhoneLayoutInflater(this, newContext); }又new出了一個(gè)PhoneLayoutInflater對(duì)象,這才是LayoutInflater.from(this)返回的LayoutInflater對(duì)象咱們?cè)倏匆幌翷ayoutInflater.from(getBaseContext())獲取LayoutInflater方式,這個(gè)感覺(jué)在哪見(jiàn)過(guò),沒(méi)錯(cuò)就是在ContextThemeWrapper中的getSystemService方法中public Object getSystemService(String name) { if (LAYOUT_INFLATER_SERVICE.equals(name)) { if (mInflater == null) { mInflater = LayoutInflater.from(getBaseContext()).cloneInContext(this); } return mInflater; } return getBaseContext().getSystemService(name); }其實(shí)LayoutInflater.from(getBaseContext())獲取LayoutInflater對(duì)象就是LayoutInflater.from(this)獲取的LayoutInflater對(duì)象在其沒(méi)有執(zhí)行cloneInContext(this)方法時(shí)創(chuàng)建的PhoneLayoutInflater對(duì)象。再一個(gè)就是LayoutInflater.from(getApplication());獲取LayoutInflater對(duì)象方式,因?yàn)間etApplication()獲取的是全局的Application對(duì)象,其內(nèi)部的ContextImpl對(duì)象也不同,所以得到的LayoutInflater對(duì)象和之前兩個(gè)也不同,還有就是不管在哪個(gè)Activity中g(shù)etApplication()獲取的Context都是同一個(gè)對(duì)象,所以LayoutInflater.from(getApplication());獲取的LayoutInflater對(duì)象都是同一個(gè)。好了,這就是為什么不同的Context對(duì)象獲取LayoutInflater是不同的對(duì)象。從剛開(kāi)始的getBaseContext(); android.app.ContextImpl@41882338就可以看出getBaseContext()獲取的是ContextImpl對(duì)象,和getApplication().getBaseContext(); android.app.ContextImpl@41870230獲取的都是同一個(gè)ContextImpl對(duì)象。
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注