国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 學(xué)院 > 開(kāi)發(fā)設(shè)計(jì) > 正文

不同Context對(duì)象創(chuàng)建的LayoutInflater對(duì)象也不同

2019-11-09 16:31:52
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

創(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ì)象。


發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 台北县| 平果县| 正阳县| 清河县| 金寨县| 武夷山市| 松溪县| 旬邑县| 滁州市| 济源市| 股票| 醴陵市| 贺兰县| 南华县| 同仁县| 丽江市| 思茅市| 济源市| 阿尔山市| 五台县| 黔西县| 缙云县| 泽库县| 庄河市| 通江县| 阳高县| 德州市| 道孚县| 贵南县| 石泉县| 筠连县| 双流县| 南木林县| 台中县| 错那县| 威远县| 宿州市| 长沙县| 思南县| 武功县| 子长县|