Activity 初始化成员 使用 getApplicationContext()

之前以为Activity在构造时(在初始化类成员时使用),getApplicationContext()就可以使用,因为当时看源码是发现getApplicationContex()最终会调到mBase, 而mBase则是ContextWrapper的一个内部成员,而mBase 在 ContextWrapper()构造时也会被赋值:

    public ContextWrapper(Context base) {
        mBase = base;
    }

而因为ContextWrapper是Acticity的父类,因此在初始化Activity对象的成员时,ConextWrapper对象应该已经构造完了,那么mBase应该是可用的,那么getApplicationContext()应该也是可用的。

试了一把,果然不行,直接NPE. 后来结合老罗的Activity启动分析: http://blog.csdn.net/luoshengyang/article/details/8201936

发现,Activity在构造时比较没节操,Activity没有自定义ctor,直接用默认的无参ctor, 那么调到父类ContextThemeWrapper的无参ctor:

public ContextThemeWrapper() {
        super(null);
    }
而ContextThemeWrapper的父类就是ContextWrapper, 那么mBase就是null,所以:

    @Override
    public Context getApplicationContext() {
        return mBase.getApplicationContext();
    }
必然NPE.

而mbase的赋值是在构造启动Activity时,ActivityThread的performLaunchActivity(), 在

Activity activity = null;
        try {
            java.lang.ClassLoader cl = r.packageInfo.getClassLoader(); 
            activity = mInstrumentation.newActivity(
                    cl, component.getClassName(), r.intent); // 构造了Activity
            StrictMode.incrementExpectedActivityCount(activity.getClass());
            r.intent.setExtrasClassLoader(cl);
            if (r.state != null) {
                r.state.setClassLoader(cl);
            }
        } catch (Exception e) {
            if (!mInstrumentation.onException(activity, e)) {
                throw new RuntimeException(
                    "Unable to instantiate activity " + component
                    + ": " + e.toString(), e);
            }
        }

        try {
            Application app = r.packageInfo.makeApplication(false, mInstrumentation); //构造/取得AppContext

            if (localLOGV) Slog.v(TAG, "Performing launch of " + r);
            if (localLOGV) Slog.v(
                    TAG, r + ": app=" + app
                    + ", appName=" + app.getPackageName()
                    + ", pkg=" + r.packageInfo.getPackageName()
                    + ", comp=" + r.intent.getComponent().toShortString()
                    + ", dir=" + r.packageInfo.getAppDir());

            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, 这一步将构造的appContext放入到Activity, 赋值给mBase.
                        r.ident, app, r.intent, r.activityInfo, title, r.parent,
                        r.embeddedID, r.lastNonConfigurationInstances, config);

也就是过,最保险的使用是在Activity的onCreate()及以后就可以了.


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值