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

首頁 > 學(xué)院 > 開發(fā)設(shè)計 > 正文

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

2019-11-09 17:35:31
字體:
供稿:網(wǎng)友

創(chuàng)建LayoutInflater對象,根據(jù)所傳的上下文對象不同,創(chuàng)建出來的LayoutInflater對象也不同,在不同Activity中創(chuàng)建的LayoutInflater對象也不同,先來看一下,

 Activity中的獲取LayoutInflater對象及打印的對象地址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對象及打印的對象地址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方法中的實現(xiàn),其實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);其實是一個意思,所以他們獲取的對象都是一樣的,那為什么不同上下文對象獲取的LayoutInflater對象也不同呢,因為不同Context對象中的mBase(ContextImpl)對象不同,LayoutInflater就是在ContextImpl中創(chuàng)建的,所以創(chuàng)建的對象不同

下面咱來看一下LayoutInflater創(chuàng)建過程,咱們來跟蹤一下代碼,就拿LayoutInflater.from(this)來說,看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()方法,因為傳的是this,即是Activity對象,Activity是也是Context對象,他們的繼承關(guān)系為:Activity -> ContextThemeWrapper -> ContextWrapper -> Context。所以看Context的子類是否重寫了getSystemService()方法,正好ContextThemeWrapper重寫了,Activity也重寫了,但和LayoutInflater沒有關(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);    }一開始的時候,mInflater肯定是為null,執(zhí)行LayoutInflater.from(getBaseContext())方法,又回到了剛開始的LayoutInflater.from()方法,不一樣的是這次上下文的對象是ContextImpl對象,為什么是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又是通過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)],返回的對象是new ContextImpl出來的,所以之前的getBaseContext()獲取的就是ContextImpl對象。所以不同對象的Context中的ContextImpl對象就不同,所以創(chuàng)建出來的LayoutInflater的對象可能就不同,往下看

所以我們再看LayoutInflater.from()中的context.getSystemService(Context.LAYOUT_INFLATER_SERVICE)語句,這個context就是ContextImpl對象,看其方法

@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;    }我們在跟進(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);    }它會先從cache中獲取,如果沒有就去創(chuàng)建createService,因為其實抽象的,所以看其實現(xiàn)類

registerService(Context.LAYOUT_INFLATER_SERVICE, LayoutInflater.class,                new CachedServiceFetcher<LayoutInflater>() {            @Override            public LayoutInflater createService(ContextImpl ctx) {                return new PhoneLayoutInflater(ctx.getOuterContext());            }});到這里終于看到了LayoutInflater 對象 PhoneLayoutInflater,其實這還不是LayoutInflater.from(this)的最終對象,看ContextThemeWrapper 的mInflater = LayoutInflater.from(getBaseContext()).cloneInContext(this);其實他在得到對象的時候又clone了一個

public LayoutInflater cloneInContext(Context newContext) {        return new PhoneLayoutInflater(this, newContext);    }又new出了一個PhoneLayoutInflater對象,這才是LayoutInflater.from(this)返回的LayoutInflater對象咱們再看一下LayoutInflater.from(getBaseContext())獲取LayoutInflater方式,這個感覺在哪見過,沒錯就是在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);    }其實LayoutInflater.from(getBaseContext())獲取LayoutInflater對象就是LayoutInflater.from(this)獲取的LayoutInflater對象在其沒有執(zhí)行cloneInContext(this)方法時創(chuàng)建的PhoneLayoutInflater對象。再一個就是LayoutInflater.from(getApplication());獲取LayoutInflater對象方式,因為getApplication()獲取的是全局的Application對象,其內(nèi)部的ContextImpl對象也不同,所以得到的LayoutInflater對象和之前兩個也不同,還有就是不管在哪個Activity中g(shù)etApplication()獲取的Context都是同一個對象,所以LayoutInflater.from(getApplication());獲取的LayoutInflater對象都是同一個。

好了,這就是為什么不同的Context對象獲取LayoutInflater是不同的對象。從剛開始的getBaseContext();   android.app.ContextImpl@41882338就可以看出getBaseContext()獲取的是ContextImpl對象,和getApplication().getBaseContext();   android.app.ContextImpl@41870230獲取的都是同一個ContextImpl對象。


發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 台前县| 德惠市| 山东省| 永安市| 新宁县| 清流县| 平山县| 丽水市| 湟中县| 黎平县| 北川| 科尔| 天峻县| 日喀则市| 湄潭县| 伊宁县| 肃宁县| 微博| 萨迦县| 丁青县| 德江县| 三河市| 苍梧县| 曲麻莱县| 金溪县| 固阳县| 丹寨县| 丰台区| 齐齐哈尔市| 邳州市| 宣汉县| 岚皋县| 天全县| 桂东县| 紫金县| 贵港市| 大化| 应城市| 共和县| 广饶县| 辽阳县|