理解Context

前言

  • 在android中,不管是应用程序开发还是framework开发,Java层有两个android基础知识点是随处可见的。一是Context,二是android消息机制(Looper、Handler)。
  • 在android系统中,如果要访问一些特定的类或资源,就必须通过Context来完成,如调用Context的getAssets()和getResource()方法访问资源。又比如,在应用程序开发中,android重要组件Service、BroadcastReceiver、Activity等都会使用到Context的相关方法,所以非常有必要了解它的原理。

Context概要

从谷歌对Context的介绍可知:

  • Context是一个应用程序环境信息的接口,表示上下文的意思
  • Context是一个抽象类,android系统提供了该抽象类的具体实现类,即ContextImpl类,这里用到一种代理模式
  • 通过Context类可以获取应用程序的资源和类,也可以进行应用程序操作,如启动Activity、发送广播、接收Intent信息等

一个应用程序中的Context实例对象个数计算公式:

总Context个数 = Activity个数 + Service个数 + 1 (Application Context)

由于Service类和Activity类都是继承Context的,应用程序被启动之后,android框架还会为应用程序创建一个全局的Application对应的Context对象,所以应用程序Context的总个数等于Service和Activity的总个数加上全局的Application Context。需要注意的是,为了避免内存泄漏,在应用程序中应尽量使用Application Context,而不是其他Context。

Context相关类的继承关系如下:

Context整体框架

  • Context是基类,是一个abstract类,Activity、Service、Application都是间接地继承它

  • ContextImpl类继承了Context,它是Context的真正实现

  • ContextWrapper类只是一个包装而已,ContextWrapper构造函数中必须包含一个真正的Context引用,即mBase,ContextWrapper类中的变量mBase是一个ContextImpl对象,同时ContextWrapper中提供了attachBaseContext()用于给ContextWrapper对象中指定真正的Context对象,调用ContextWrapper的方法都会被转向其所包含的真正的Context对象,而ContextImpl的变量mOuterContext是一个Context对象

  • 当我们在应用程序中调用Context的方法时,实际是进入框架层之后通过使用mBase对象来调用相应的方法。由于mBase是一个ContextImpl对象,ContextImpl类真正实现了Context中的所有函数,所以这个调用就会进入ContextImpl类里的相应方法,这里用到了代理模式。当在ContextImpl类的方法工作结束之后,又通过mOuterContext对象的方法来回调应用程序。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    public abstract class Context {
    // 获取AssetManager对象
    public abstract AssetManager getAssets();
    // 获取Resource对象
    public abstract Resources getResources();
    // 获取ContentResolver对象
    public abstract ContentResolver getContentResolver();
    // 获取Application Context对象
    public abstract Context getApplicationContext();
    // 启动Service
    @Nullable
    public abstract ComponentName startService(Intent service);
    // 启动Activity
    public abstract void startActivity(@RequiresPermission Intent intent);
    ...
    }

    Context是一个抽象类,其中有几个非常重要的方法,比如getAssets()方法、getResource()方法,它们都经常用于应用程序开发,以获得资源。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    public class ContextWrapper extends Context {
    // mBase是一个ContextImpl实例,一般在创建Application、Service和Activity时给它赋值
    Context mBase;
    public ContextWrapper(Context base) {
    mBase = base;
    }
    // 创建Application、Service和Activity时会调用该方法给mBase赋值
    protected void attachBaseContext(Context base) {
    if (mBase != null) {
    throw new IllegalStateException("Base context already set");
    }
    mBase = base;
    }
    }

    ContextWrapper类继承与Context,在attachBaseContext()方法里对变量mBase赋值。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    public class ContextThemeWrapper extends ContextWrapper {
    private int mThemeResource;
    private Resources.Theme mTheme;
    private LayoutInflater mInflater;
    public ContextThemeWrapper(Context base, @StyleRes int themeResId) {
    super(base);
    mThemeResource = themeResId;
    }
    ...
    }

    ContextThemeWrapper类继承于ContextWrapper类。如其名所示,其内部包含了与主题相关的接口,这里所说的主题就是指在AndroidManifest.xml中通过android:theme为Application元素或者Activity对象指定的主题。

    1
    2
    3
    4
    public class Activity extends ContextThemeWrapper implements LayoutInflater.Factory2, Window.Callback, KeyEvent.Callback, OnCreateContextMenuListener, ComponentCallbacks2,
    Window.OnWindowDismissedCallback, WindowControllerCallback {
    ...
    }

    Activity类继承于ContextThemeWrapper,而ContextThemeWrapper类又继承ContextWrapper,ContextWrapper直接继承Context,所以Activity是Context。

    1
    2
    3
    public abstract class Service extends ContextWrapper implements ComponentCallbacks2 {
    ...
    }

    Service类是一个抽象类,它继承ContextWrapper,而ContextWrapper又继承Context,所以Service也是一个Context。

    1
    2
    3
    public class Application extends ContextWrapper implements ComponentCallbacks2 {
    ...
    }

    同理,Application类继承ContextWrapper,而ContextWrapper又继承Context,所以Application也是一个Context。

创建Context

每一个应用程序在客户端都是从ActivityThread类开始的,创建Context对象也是在该类中完成的,具体创建ContextImpl类的地方一共有7处,分别如下:

  • 在PackageInfo.makeApplication()中
  • 在performLauncherActivity()中
  • 在handleCreateBackupAgent()中
  • 在handleCreateService()中
  • 在handleBindApplication()中
  • 还是在handleBindApplication()中
  • 在attach()中(attach方法仅在framework进程启动调用,应用程序运行时不会调用该方法)

Application Context创建过程

每个应用程序在第一次启动时,都会首先创建一个Application对象,默认的Application是应用程序的包名,用户可以重载默认的Application。在android应用程序中,可以使用getApplicationContext()方法来获取应用程序的全局Context,这意味着该应用程序的任何位置通过此方法都能得到该Context对象。

Application Context关系图

从这个图可以知道,Application继承于ContextWrapper,ContextWrapper继承于Context,ContextImpl也继承于Context,它是Context的真正实现,即代理模式。mOuterContext对象是Application类的实例,它通过ContextImpl类的静态方法setOuterContext()来设置值。而mBase对象是一个ContextImpl实例,它通过Application的attach()方法来被赋值。

Application Context对象在应用程序启动之后,通过LoadedApk.java的makeApplication()方法创建,下面来分析Application Context的创建流程。

当应用程序进程启动之后,android系统framework框架里的ActivityManagerService核心服务会调入应用程序客户端ActivityThread类的scheduleLaunchActivity()方法里。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
ActivityInfo info, Configuration curConfig, Configuration overrideConfig,
CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor,
int procState, Bundle state, PersistableBundle persistentState,
List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents,
boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) {
updateProcessState(procState, false);
ActivityClientRecord r = new ActivityClientRecord();
r.token = token;
r.ident = ident;
r.intent = intent;
r.referrer = referrer;
r.voiceInteractor = voiceInteractor;
r.activityInfo = info;
r.compatInfo = compatInfo;
r.state = state;
r.persistentState = persistentState;
r.pendingResults = pendingResults;
r.pendingIntents = pendingNewIntents;
r.startsNotResumed = notResumed;
r.isForward = isForward;
r.profilerInfo = profilerInfo;
r.overrideConfig = overrideConfig;
updatePendingConfiguration(curConfig);
sendMessage(H.LAUNCH_ACTIVITY, r);
}

首先,这个方法会生成ActivityClientRecord对象r,并且给它里面的变量token赋值,这个token变量是AMS中ActivityRecord类里的一个binder对象,这个token对象会同时传到应用程序ActivityThread和WMS。最后scheduleLaunchActivity()方法通过H类发送一个LAUNCH_ACTIVITY消息,H类继承与Handler。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
private class H extends Handler {
public static final int LAUNCH_ACTIVITY = 100;
public static final int PAUSE_ACTIVITY = 101;
public static final int PAUSE_ACTIVITY_FINISHING= 102;
public static final int STOP_ACTIVITY_SHOW = 103;
public static final int STOP_ACTIVITY_HIDE = 104;
public static final int SHOW_WINDOW = 105;
public static final int HIDE_WINDOW = 106;
public static final int RESUME_ACTIVITY = 107;
public static final int SEND_RESULT = 108;
public static final int DESTROY_ACTIVITY = 109;
public static final int BIND_APPLICATION = 110;
public static final int EXIT_APPLICATION = 111;
public static final int NEW_INTENT = 112;
public static final int RECEIVER = 113;
public static final int CREATE_SERVICE = 114;
public static final int SERVICE_ARGS = 115;
public static final int STOP_SERVICE = 116;
public static final int CONFIGURATION_CHANGED = 118;
public static final int CLEAN_UP_CONTEXT = 119;
public static final int GC_WHEN_IDLE = 120;
public static final int BIND_SERVICE = 121;
public static final int UNBIND_SERVICE = 122;
public static final int DUMP_SERVICE = 123;
public static final int LOW_MEMORY = 124;
public static final int ACTIVITY_CONFIGURATION_CHANGED = 125;
public static final int RELAUNCH_ACTIVITY = 126;
public static final int PROFILER_CONTROL = 127;
public static final int CREATE_BACKUP_AGENT = 128;
public static final int DESTROY_BACKUP_AGENT = 129;
public static final int SUICIDE = 130;
public static final int REMOVE_PROVIDER = 131;
public static final int ENABLE_JIT = 132;
public static final int DISPATCH_PACKAGE_BROADCAST = 133;
public static final int SCHEDULE_CRASH = 134;
public static final int DUMP_HEAP = 135;
public static final int DUMP_ACTIVITY = 136;
public static final int SLEEPING = 137;
public static final int SET_CORE_SETTINGS = 138;
public static final int UPDATE_PACKAGE_COMPATIBILITY_INFO = 139;
public static final int TRIM_MEMORY = 140;
public static final int DUMP_PROVIDER = 141;
public static final int UNSTABLE_PROVIDER_DIED = 142;
public static final int REQUEST_ASSIST_CONTEXT_EXTRAS = 143;
public static final int TRANSLUCENT_CONVERSION_COMPLETE = 144;
public static final int INSTALL_PROVIDER = 145;
public static final int ON_NEW_ACTIVITY_OPTIONS = 146;
public static final int CANCEL_VISIBLE_BEHIND = 147;
public static final int BACKGROUND_VISIBLE_BEHIND_CHANGED = 148;
public static final int ENTER_ANIMATION_COMPLETE = 149;
public static final int START_BINDER_TRACKING = 150;
public static final int STOP_BINDER_TRACKING_AND_DUMP = 151;
public static final int MULTI_WINDOW_MODE_CHANGED = 152;
public static final int PICTURE_IN_PICTURE_MODE_CHANGED = 153;
public static final int LOCAL_VOICE_INTERACTION_STARTED = 154;
public void handleMessage(Message msg) {
if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
switch (msg.what) {
case LAUNCH_ACTIVITY: {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
final ActivityClientRecord r = (ActivityClientRecord) msg.obj;
r.packageInfo = getPackageInfoNoCheck(
r.activityInfo.applicationInfo, r.compatInfo);
handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
} break;
...
}
}
...
}

从H类的定义可知,它是一个继承Handler的ActivityThread内部类,主要用来在ActivityThread内部分发消息。当scheduleLaunchActivity()方法发送了LAUNCH_ACTIVITY消息之后,最终系统会分发这个消息进入H类中的handleMessage()方法,handleMessage()方法则调用handleLaunchActivity()方法来继续处理。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
unscheduleGcIdler();
mSomeActivitiesChanged = true;
if (r.profilerInfo != null) {
mProfiler.setProfiler(r.profilerInfo);
mProfiler.startProfiling();
}
handleConfigurationChanged(null, null);
if (localLOGV) Slog.v(
TAG, "Handling launch of " + r);
WindowManagerGlobal.initialize();
// 首先调用performLaunchActivity()方法,这个方法主要用于创建Application Context和Activity Context,创建Activity Context的过程实际上就是创建Activity的过程
Activity a = performLaunchActivity(r, customIntent);
if (a != null) {
r.createdConfig = new Configuration(mConfiguration);
reportSizeConfigurations(r);
Bundle oldState = r.state;
// 调用handleResumeActivity()方法主要是来进入Activity的生命周期onResume()方法
handleResumeActivity(r.token, false, r.isForward,
!r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);
if (!r.activity.mFinished && r.startsNotResumed) {
performPauseActivityIfNeeded(r, reason);
if (r.isPreHoneycomb()) {
r.state = oldState;
}
}
} else {
try {
ActivityManagerNative.getDefault()
.finishActivity(r.token, Activity.RESULT_CANCELED, null,
Activity.DONT_FINISH_TASK_WITH_ACTIVITY);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}
}

接下来看performLaunchActivity()这个方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
ActivityInfo aInfo = r.activityInfo;
if (r.packageInfo == null) {
r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
Context.CONTEXT_INCLUDE_CODE);
}
ComponentName component = r.intent.getComponent();
if (component == null) {
component = r.intent.resolveActivity(
mInitialApplication.getPackageManager());
r.intent.setComponent(component);
}
if (r.activityInfo.targetActivity != null) {
component = new ComponentName(r.activityInfo.packageName,
r.activityInfo.targetActivity);
}
Activity activity = null;
try {
java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
StrictMode.incrementExpectedActivityCount(activity.getClass());
r.intent.setExtrasClassLoader(cl);
r.intent.prepareToEnterProcess();
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 {
// 变量packageInfo是一个LoadedApk类型的对象,通过它的makeApplication()方法来创建Application Context
Application app = r.packageInfo.makeApplication(false, mInstrumentation);
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) {
// 如果变量Activity不为空,还会调用createBaseContextForActivity()方法来创建Activity的 上下文Context
Context appContext = createBaseContextForActivity(r, activity);
CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
Configuration config = new Configuration(mCompatConfiguration);
if (r.overrideConfig != null) {
config.updateFrom(r.overrideConfig);
}
if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "
+ r.activityInfo.name + " with config " + config);
Window window = null;
if (r.mPendingRemoveWindow != null && r.mPreserveWindow) {
window = r.mPendingRemoveWindow;
r.mPendingRemoveWindow = null;
r.mPendingRemoveWindowManager = null;
}
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, window);
if (customIntent != null) {
activity.mIntent = customIntent;
}
r.lastNonConfigurationInstances = null;
activity.mStartedActivity = false;
int theme = r.activityInfo.getThemeResource();
if (theme != 0) {
activity.setTheme(theme);
}
activity.mCalled = false;
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
if (!activity.mCalled) {
throw new SuperNotCalledException(
"Activity " + r.intent.getComponent().toShortString() +
" did not call through to super.onCreate()");
}
r.activity = activity;
r.stopped = true;
if (!r.activity.mFinished) {
activity.performStart();
r.stopped = false;
}
if (!r.activity.mFinished) {
if (r.isPersistable()) {
if (r.state != null || r.persistentState != null) {
mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state,
r.persistentState);
}
} else if (r.state != null) {
mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
}
}
if (!r.activity.mFinished) {
activity.mCalled = false;
if (r.isPersistable()) {
mInstrumentation.callActivityOnPostCreate(activity, r.state,
r.persistentState);
} else {
mInstrumentation.callActivityOnPostCreate(activity, r.state);
}
if (!activity.mCalled) {
throw new SuperNotCalledException(
"Activity " + r.intent.getComponent().toShortString() +
" did not call through to super.onPostCreate()");
}
}
}
r.paused = true;
mActivities.put(r.token, r);
} catch (SuperNotCalledException e) {
throw e;
} catch (Exception e) {
if (!mInstrumentation.onException(activity, e)) {
throw new RuntimeException(
"Unable to start activity " + component
+ ": " + e.toString(), e);
}
}
return activity;
}

下面是用makeApplication()方法来创建应用程序Application Context。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
public Application makeApplication(boolean forceDefaultAppClass,
Instrumentation instrumentation) {
if (mApplication != null) {
return mApplication; // 变量mApplication是LoadedApk类中的全局变量,它是一个Application对象,由于Application继承Context,所以他是一个Context对象
}
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "makeApplication");
Application app = null;
String appClass = mApplicationInfo.className;
if (forceDefaultAppClass || (appClass == null)) {
appClass = "android.app.Application";
}
try {
java.lang.ClassLoader cl = getClassLoader();
if (!mPackageName.equals("android")) {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
"initializeJavaContextClassLoader");
initializeJavaContextClassLoader();
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
}
// 这里通过ContextImpl的静态方法createAppContext()创建一个ContextImpl实例
ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
// 通过newApplication()方法创建一个Application对象app,在newApplication()方法过程中,会把appContext对象作为参数传递到Application中,赋值给ContextWrapper类里的mBase对象
app = mActivityThread.mInstrumentation.newApplication(
cl, appClass, appContext);
// 当Application对象app创建好之后,就把该app对象通过setOuterContext()方法赋值给ContextImpl的mOuterContext变量,最后把该app对象赋值给LoadedApk的全局变量mApplication
appContext.setOuterContext(app);
} catch (Exception e) {
if (!mActivityThread.mInstrumentation.onException(app, e)) {
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
throw new RuntimeException(
"Unable to instantiate application " + appClass
+ ": " + e.toString(), e);
}
}
mActivityThread.mAllApplications.add(app);
mApplication = app;
if (instrumentation != null) {
try {
instrumentation.callApplicationOnCreate(app);
} catch (Exception e) {
if (!instrumentation.onException(app, e)) {
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
throw new RuntimeException(
"Unable to create application " + app.getClass().getName()
+ ": " + e.toString(), e);
}
}
}
SparseArray<String> packageIdentifiers = getAssets(mActivityThread)
.getAssignedPackageIdentifiers();
final int N = packageIdentifiers.size();
for (int i = 0; i < N; i++) {
final int id = packageIdentifiers.keyAt(i);
if (id == 0x01 || id == 0x7f) {
continue;
}
rewriteRValues(getClassLoader(), packageIdentifiers.valueAt(i), id);
}
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
return app;
}

下面是newApplication()方法把appContext对象赋值给ContextWrapper类mBase对象的过程,以及setOuterContext()方法给ContextImpl类mOuterContext变量的赋值过程。

1
2
3
4
5
public Application newApplication(ClassLoader cl, String className, Context context)
throws InstantiationException, IllegalAccessException,
ClassNotFoundException {
return newApplication(cl.loadClass(className), context);
}
1
2
3
4
5
6
7
static public Application newApplication(Class<?> clazz, Context context)
throws InstantiationException, IllegalAccessException,
ClassNotFoundException {
Application app = (Application)clazz.newInstance();
app.attach(context);
return app;
}

newApplication()方法首先创建了一个Application类型的对象app,然后调用它的attach()方法把前面传过来的ContextImpl对象赋值给ContextWrapper类的mBase对象,而在newApplicatio()方法最后还会把该新创建的Application对象app返回到上一个方法。接下来看看attach()方法。

1
2
3
4
/* package */ final void attach(Context context) {
attachBaseContext(context);
mLoadedApk = ContextImpl.getImpl(context).mPackageInfo;
}

attach()方法通过调用父类的attachBaseContext()方法,即调用ContextWrapper类的attachBaseContext()方法将ContextImpl对象赋值给ContextWrapper类的mBase对象。

1
2
3
4
5
6
7
8
9
10
11
public class ContextWrapper extends Context {
Context mBase;
...
protected void attachBaseContext(Context base) {
if (mBase != null) {
throw new IllegalStateException("Base context already set");
}
mBase = base;
}
...
}

回到前面的makeApplication()方法中,这个过程结束时候就会调用setOuterContext()方法把Application对象赋值给ContextImpl的mOuterContext变量。

1
2
3
4
5
6
7
8
class ContextImpl extends Context {
private Context mOuterContext;
...
final void setOuterContext(Context context) {
mOuterContext = context;
}
...
}

至此,关于Application Context的创建过程就介绍完毕。

Application Context的获取

  • 在应用程序中,可以直接通过getApplicationContext()方法来获得Application Context,就会进入到框架层ContextWrapper类的getApplicationContext()方法中,下面就这个方法来开始分析Application Context的获得。

  • 这个过程总共三个步骤,主要通过分别调用ContextWrapper、ContextImpl和LoadedApk的getApplicationContext()方法来实现。

    1
    2
    3
    4
    @Override
    public Context getApplicationContext() {
    return mBase.getApplicationContext();
    }

    变量mBase是ContextImpl类型的对象,此处调用它的getApplicationContext()方法进入到ContextImpl类的getApplicationContext()方法中进一步操作。

    1
    2
    3
    4
    5
    @Override
    public Context getApplicationContext() {
    return (mPackageInfo != null) ?
    mPackageInfo.getApplication() : mMainThread.getApplication();
    }

    在ContextImpl类的getApplicationContext()方法中,变量mPackageInfo是一个LoadedApk对象,而变量mMainThread是一个ActivityThread对象,由于应用程序已经启动,mPackageInfo不为空,于是调用LoadedApk的getApplication()方法,以下是LoadedApk的getApplication()方法实现。

    1
    2
    3
    Application getApplication() {
    return mApplication;
    }

    LoadedApk的getApplication()方法返回在makeApplication()方法中创建的全局变量mApplication对象。

Activity Context创建过程

Activity继承Context,当通过Activity的子类调用Activity方法时,就会间接连入它父类Context的方法,既然要调用Activity里Context的相关方法,就必须先创建Activity Context上下文环境,接下来看看Activity运行上下文Context的创建过程。

Activity Context创建过程的步骤与Application Context创建过程类似,当启动一个Activity的时候,framework层会通过Binder IPC向AMS发出创建Activity的请求,在AMS服务响应后,会调用scheduleLaunchActivity()方法,scheduleLaunchActivity()方法最后会调用handleLaunchActivity()方法,handleLaunchActivity()方法最后又调用了performLaunchActivity()方法来创建Activity Context。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
...
Activity activity = null;
try {
java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
// newActivity()方法用于创建一个Activity实例,当创建好Activity实例之后就赋值给activity变量
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
StrictMode.incrementExpectedActivityCount(activity.getClass());
r.intent.setExtrasClassLoader(cl);
r.intent.prepareToEnterProcess();
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 {
...
if (activity != null) {
// 调用createBaseContextForActivity()方法来创建ContextImpl类型对象appContext
Context appContext = createBaseContextForActivity(r, activity);
CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
Configuration config = new Configuration(mCompatConfiguration);
if (r.overrideConfig != null) {
config.updateFrom(r.overrideConfig);
}
if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "
+ r.activityInfo.name + " with config " + config);
Window window = null;
if (r.mPendingRemoveWindow != null && r.mPreserveWindow) {
window = r.mPendingRemoveWindow;
r.mPendingRemoveWindow = null;
r.mPendingRemoveWindowManager = null;
}
// 调用attach()方法来将前面所创建的ContextImpl对象appContext保存在Activity内部,这样,Activity的mBase就是ContextImpl对象
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, window);
if (customIntent != null) {
activity.mIntent = customIntent;
}
r.lastNonConfigurationInstances = null;
activity.mStartedActivity = false;
int theme = r.activityInfo.getThemeResource();
if (theme != 0) {
activity.setTheme(theme);
}
activity.mCalled = false;
// 调用mInstrumentation对象的方法callActivityOnCreate()来通知Activity进入它的生命周期onCreate()方法
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
if (!activity.mCalled) {
throw new SuperNotCalledException(
"Activity " + r.intent.getComponent().toShortString() +
" did not call through to super.onCreate()");
}
r.activity = activity;
r.stopped = true;
if (!r.activity.mFinished) {
activity.performStart();
r.stopped = false;
}
if (!r.activity.mFinished) {
if (r.isPersistable()) {
if (r.state != null || r.persistentState != null) {
mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state,
r.persistentState);
}
} else if (r.state != null) {
mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
}
}
if (!r.activity.mFinished) {
activity.mCalled = false;
if (r.isPersistable()) {
mInstrumentation.callActivityOnPostCreate(activity, r.state,
r.persistentState);
} else {
mInstrumentation.callActivityOnPostCreate(activity, r.state);
}
if (!activity.mCalled) {
throw new SuperNotCalledException(
"Activity " + r.intent.getComponent().toShortString() +
" did not call through to super.onPostCreate()");
}
}
}
r.paused = true;
mActivities.put(r.token, r);
} catch (SuperNotCalledException e) {
throw e;
} catch (Exception e) {
if (!mInstrumentation.onException(activity, e)) {
throw new RuntimeException(
"Unable to start activity " + component
+ ": " + e.toString(), e);
}
}
return activity;
}

接下来开始分析这些过程。

  • 首先,Instrumentation类创建Activity实例。
1
2
3
4
5
6
public Activity newActivity(ClassLoader cl, String className,
Intent intent)
throws InstantiationException, IllegalAccessException,
ClassNotFoundException {
return (Activity)cl.loadClass(className).newInstance();
}

cl是一个类加载器,className是一个Activity子类的名字,在应用程序开发中,都用一个子类来继承Activity,所以(Activity)cl.loadClass(className).newInstance()会创建一个子Activity类的实例。子Activity实例在创建过程中会调用父类Activity的默认构造方法。之后Activity的attach()方法来完成初始化过程。

  • 接着,调用createBaseContextForActivity()方法来创建一个ContextImpl对象。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    private Context createBaseContextForActivity(ActivityClientRecord r, final Activity activity) {
    int displayId = Display.DEFAULT_DISPLAY;
    try {
    displayId = ActivityManagerNative.getDefault().getActivityDisplayId(r.token);
    } catch (RemoteException e) {
    throw e.rethrowFromSystemServer();
    }
    ContextImpl appContext = ContextImpl.createActivityContext(
    this, r.packageInfo, r.token, 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;
    }

    ActivityThread的createBaseContextForActivity()方法通过调用ContextImpl类的createActivityContext()方法,来创建ContextImpl类型实例对象appContext,而createActivityContext()方法的真正实现就是new 了一个ContextImpl实例。这里还通过调用setOuterContext()方法把前面创建的activity实例对象赋值给ContextImpl类的mOuterContext变量。这样,以后ContextImpl也可以访问Activity中的变量和方法,接下来分别是ContextImpl的创建过程和setOuterContext()方法的赋值过程。

    1
    2
    3
    4
    5
    6
    7
    static ContextImpl createActivityContext(ActivityThread mainThread,
    LoadedApk packageInfo, IBinder activityToken, int displayId,
    Configuration overrideConfiguration) {
    if (packageInfo == null) throw new IllegalArgumentException("packageInfo");
    return new ContextImpl(null, mainThread, packageInfo, activityToken, null, 0,
    null, overrideConfiguration, displayId);
    }

    createActivityContext()方法首先会判断packageInfo是否为空,packageInfo是一个LoadedApk对象,如果为空就会抛出IllegalArgumentException异常,因为应用程序已启动,packageInfo不为空,所以通过new关键字创建了一个ContextImpl实例,然后return回去。接下来了解setOuterContext()方法。

    1
    2
    3
    final void setOuterContext(Context context) {
    mOuterContext = context;
    }

    参数context代表前面传过来的activity对象,ContextImpl的setOuterContext()方法把这个对象赋值给它的全局变量mOuterContext,这样ContextImpl就可以访问Activity中的方法。

  • 接下来调用Activity类的attach()方法来初始化正在启动的Activity。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    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,
    Window window) {
    // 首先调用Activity父类ConetextThemeWrapper的attachBaseContext()方法,将参数context所表示的一个ContextImpl对象保存在ContextThemeWrapper类和ContextWrapper类中
    attachBaseContext(context);
    mFragments.attachHost(null /*parent*/);
    // 然后创建PhoneWindow对象,并且把该对象赋值给Activity类的变量mWindow,该PhoneWindow对象用来表示当前正在启动的Activity的应用程序窗口,是android中一个非常重要的概念,该应用程序窗口还有个DecorView对象,它是Activity的根视图
    mWindow = new PhoneWindow(this, window);
    mWindow.setWindowControllerCallback(this);
    // 应用程序的Activity在运行过程中,其中的PhoneWindow对象会接收到一些事件,如硬按键、触摸屏事件等,这些事件需要转发给与它关联的相应Activity来处理,转发操作通过Window.Callback接口来实现,而Activity实现了Window.Callback接口
    mWindow.setCallback(this);
    mWindow.setOnWindowDismissedCallback(this);
    mWindow.getLayoutInflater().setPrivateFactory(this);
    if (info.softInputMode != WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED) {
    mWindow.setSoftInputMode(info.softInputMode);
    }
    if (info.uiOptions != 0) {
    mWindow.setUiOptions(info.uiOptions);
    }
    mUiThread = Thread.currentThread();
    mMainThread = aThread;
    mInstrumentation = instr;
    mToken = token;
    mIdent = ident;
    mApplication = application;
    mIntent = intent;
    mReferrer = referrer;
    mComponent = intent.getComponent();
    mActivityInfo = info;
    mTitle = title;
    mParent = parent;
    mEmbeddedID = id;
    mLastNonConfigurationInstances = lastNonConfigurationInstances;
    if (voiceInteractor != null) {
    if (lastNonConfigurationInstances != null) {
    mVoiceInteractor = lastNonConfigurationInstances.voiceInteractor;
    } else {
    mVoiceInteractor = new VoiceInteractor(voiceInteractor, this, this,
    Looper.myLooper());
    }
    }
    // 在android系统中,每一个应用程序窗口都需要一个窗口管理者来管理,因此,通过调用setWindowManager()方法来为应用程序窗口PhoneWindow设置一个窗口管理者
    mWindow.setWindowManager(
    (WindowManager)context.getSystemService(Context.WINDOW_SERVICE),
    mToken, mComponent.flattenToString(),
    (info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);
    if (mParent != null) {
    mWindow.setContainer(mParent.getWindow());
    }
    mWindowManager = mWindow.getWindowManager();
    mCurrentConfig = config;
    }

    接下里分析一下ConetextThemeWrapper的attachBaseContext()方法。

    1
    2
    3
    4
    @Override
    protected void attachBaseContext(Context newBase) {
    super.attachBaseContext(newBase);
    }
    1
    2
    3
    4
    5
    6
    protected void attachBaseContext(Context base) {
    if (mBase != null) {
    throw new IllegalStateException("Base context already set");
    }
    mBase = base;
    }

    这里把前面创建的ContextImpl对象赋值给mBase。ContextImpl类是Context的一个代理类,这里通过对mBase的赋值,ContextWrapper类就可以将它的功能交给ContextImpl类来处理。

    这一步执行完成之后,当前正在启动的Activity组件的运行上下文环境Context就创建完成了,这个过程跟Activity的启动紧密相联。

  • 完成这些操作之后,会调用Instrumentation对象的方法callActivityOnCreate()来进入Activity的生命周期onCreate()方法。

    1
    2
    3
    4
    5
    public void callActivityOnCreate(Activity activity, Bundle icicle) {
    prePerformCreate(activity);
    activity.performCreate(icicle);
    postPerformCreate(activity);
    }

    Instrumentation类的callActivityOnCreate()方法主要通过调用Activity的performCreate()方法来进一步操作。

    1
    2
    3
    4
    5
    6
    final void performCreate(Bundle icicle) {
    restoreHasCurrentPermissionRequest(icicle);
    onCreate(icicle);
    mActivityTransitionState.readState(icicle);
    performCreateCommon();
    }

    根据Java的多态性,onCreate()会进入Activity子类的onCreate()方法。

    至此,Activity运行上下文环境Context的创建过程就分析完毕。

Service Context创建过程

Service继承于ContextWrapper,ContextWrapper继承于Context,所以Service也是一个Context对象,并且在android应用程序的Service中也大量调用了Context相关方法。以下开始分析Service的创建过程。

Service在启动过程中,AMS服务会被调用到ActivityThread类中,最后进入ActivityThread的handleCreateService()方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
private void handleCreateService(CreateServiceData data) {
unscheduleGcIdler();
LoadedApk packageInfo = getPackageInfoNoCheck(
data.info.applicationInfo, data.compatInfo);
Service service = null;
try {
// 首先通过加载ClassLoader对象构建Service实例
java.lang.ClassLoader cl = packageInfo.getClassLoader();
service = (Service) cl.loadClass(data.info.name).newInstance();
} catch (Exception e) {
if (!mInstrumentation.onException(service, e)) {
throw new RuntimeException(
"Unable to instantiate service " + data.info.name
+ ": " + e.toString(), e);
}
}
try {
if (localLOGV) Slog.v(TAG, "Creating service " + data.info.name);
// 接着通过ContextImpl的createAppContext()方法创建ContextImpl类型实例context,然后通过这个ContextImpl类型实例context调用setOuterContext()方法把Service对象赋值给ContextImpl的mOuterContext变量
ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
context.setOuterContext(service);
Application app = packageInfo.makeApplication(false, mInstrumentation);
// 最后调用Service的attach()方法把ContextImpl实例context赋值给ContextWrapper类的mBase变量
service.attach(context, this, data.info.name, data.token, app,
ActivityManagerNative.getDefault());
service.onCreate();
mServices.put(data.token, service);
try {
ActivityManagerNative.getDefault().serviceDoneExecuting(
data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
} catch (Exception e) {
if (!mInstrumentation.onException(service, e)) {
throw new RuntimeException(
"Unable to create service " + data.info.name
+ ": " + e.toString(), e);
}
}
}

接下来概括一下整个过程。

  • 首先是createAppContext()方法创建ContextImpl实例。

    1
    2
    3
    4
    5
    static ContextImpl createAppContext(ActivityThread mainThread, LoadedApk packageInfo) {
    if (packageInfo == null) throw new IllegalArgumentException("packageInfo");
    return new ContextImpl(null, mainThread,
    packageInfo, null, null, 0, null, null, Display.INVALID_DISPLAY);
    }
  • 然后是ContextImpl的setOuterContext()方法。

    1
    2
    3
    final void setOuterContext(Context context) {
    mOuterContext = context;
    }
  • 最后是调用Service的attach()方法。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    public final void attach(Context context, ActivityThread thread, String className,
    IBinder token, Application application, Object activityManager) {
    attachBaseContext(context);
    mThread = thread;
    mClassName = className;
    mToken = token;
    mApplication = application;
    mActivityManager = (IActivityManager)activityManager;
    mStartCompatibility = getApplicationInfo().targetSdkVersion
    < Build.VERSION_CODES.ECLAIR;
    }

    Service的attach()方法调用其父类ContextWrapper的attachBaseContext()方法以进一步操作。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    public class ContextWrapper extends Context {
    Context mBase;
    ...
    protected void attachBaseContext(Context base) {
    if (mBase != null) {
    throw new IllegalStateException("Base context already set");
    }
    mBase = base;
    }
    ...
    }

    至此,Service Context的创建过程分析完毕。

小结

  • 一个Context意味着一个场景,一个场景就是用户和操作系统交互的一种过程。比如当你打电话时,场景包括电话程序对应的界面,以及隐藏在界面后的数据;当你看短信时,场景包括短信界面,以及隐藏在后面的数据…..
  • 从语义的角度审视一下Context,android程序员把“场景”抽象为Context类,他们认为与操作系统的每一次交互都是一个场景,Activity是有界面的场景,Service是没有界面的场景。
  • 应用程序包含多个ContextImpl对象,而其内部变量mPackageInfo却指向同一个PackageInfo对象,这种设计结构一般意味着ContextImpl是一个轻量级类,而PackageInfo是一个重量级类。通过查看ContextImpl代码可知,的确是这样,ContextImpl中的大多数进行包操作的重量级函数实际上都是转向mPackageInfo对象相应的方法,即事实上是调用了同一个PackageInfo对象,因此,从系统效率的角度来看也是合理的。当然,这不是说ContextImpl代码的内容比PackageInfo的简单,因为ContextImpl更重要的功能还包含实现Context虚拟机所定义的全部功能函数。