您的位置:首页 > 移动开发

Activity 初始化成员 使用 getApplicationContext()

2014-12-11 11:50 302 查看
之前以为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()及以后就可以了.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐