5.1 理解上下文
Context 也就是上下文对象,是 Android 常用的类。
Context 意为上下文,是一个应用程序环境信息的接口。
使用场景:
1. 使用 Context 调用方法,比如启动 Activity、访问资源、调用系统级服务等。 2. 调用方法时传入 Context, 比如弹出 Toast、 创建 Dialog 等。
Activity 、 Service 和 Application 都间接地继承自 Context 。
一个应用程序进程中有多少个 Context ,这个数量等于 Activity 和 Service 的总个数加 1,1指的是 Application 的数量。
Context 是一个抽象类,它的内部定义了很多方法以及静态常量,它的具体实现为 ContextImpl。
和Cotext 相关联的类, 除了 ContextImpl ,还有 ContextWrapper、ContextThemeWrapper 和 Activity 等。
ContextImpl 和 ContextWrapper 继承自 Context ,ContextWrapper 内部包含 Context 类型的 mBase 对象,mBase 具体指向 ContextImpl。
ContextImpl 提供了很多功能,因此设计上使用了装饰模式, ContextWrapper 是装饰类, 它对 ContentImpl 进行包装, ContextWrapper 主要是起了方法传递的作用, ContextWrapper 中几乎所有的方法都是调用 ContextImpl 的相应方法来实现的。
ContextThemeWrapper、Service 和 Application 都继承自 ContextWrapper, 这样他们都可以通过 mBase 来使用 Context 的方法,同时它们也是装饰类,在ContextWrapper 的基础上又添加了不同的功能。
ContextThemeWrapper 中包含和主题相关的方法(比如 getTheme 方法),因此,需要主题的 Activity 继承 ContextThemeWrapper,而不需要主题的 Service 继承 ContextWrapper。
Context 的关联类采用了装饰模式:
- 使用者(比如 Servcice) 能够方便地使用 Context。
- 如果ContextImpl 发生了变化,它的装饰类 ContextWrapper 不需要做任何修改。
- ContextImpl 的实现不会暴露给使用者,使用者也不必关心 ContextImpl 的实现。
- 通过组合而非继承的方式,拓展 ContextImpl 的功能,在运行时选择不同的装饰类,实现不同的功能。
5.2 Application Context 的创建过程
通过getApplicationContext 来获取应用程序全局的 Application Context.
在一个应用程序启动完成后,应用程序就会有一个全局的 Application Context 。
Application Context 的创建过程:
// frameworks/base/core/java/android/app/ActivityThread.java
1074 private class ApplicationThread extends IApplicationThread.Stub {
1075 private static final String DB_INFO_FORMAT = " %8s %8s %14s %14s %s";
1076
1077 public final void scheduleReceiver(Intent intent, ActivityInfo info,
1078 CompatibilityInfo compatInfo, int resultCode, String data, Bundle extras,
1079 boolean sync, int sendingUser, int processState) {
1080 updateProcessState(processState, false);
1081 ReceiverData r = new ReceiverData(intent, resultCode, data, extras,
1082 sync, false, mAppThread.asBinder(), sendingUser);
1083 r.info = info;
1084 r.compatInfo = compatInfo;
1085 sendMessage(H.RECEIVER, r); // 向 H类 发送消息
1086 }
class H extends Handler {
public static final int RECEIVER = 113;
}
public void handleMessage(Message msg) {
2187 if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
2188 switch (msg.what) {
...
case RECEIVER:
2202 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "broadcastReceiveComp");
2203 handleReceiver((ReceiverData)msg.obj); // 主要是该方法
2204 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2205 break;
H 继承自 Handler ,是 ActivityThread 的内部类。
这里对比原书,android 12 的流程还是发生了一些变化
4448 private void handleReceiver(ReceiverData data) {
4449
4450
4451 unscheduleGcIdler();
4452
4453 String component = data.intent.getComponent().getClassName();
4454
4455 LoadedApk packageInfo = getPackageInfoNoCheck(
4456 data.info.applicationInfo, data.compatInfo);
4457
4458 IActivityManager mgr = ActivityManager.getService();
4459
4460 Application app;
4461 BroadcastReceiver receiver;
4462 ContextImpl context;
4463 try {
4464 app = packageInfo.makeApplication(false, mInstrumentation);
4465 context = (ContextImpl) app.getBaseContext();
4466 if (data.info.splitName != null) {
4467 context = (ContextImpl) context.createContextForSplit(data.info.splitName);
4468 }
4469 if (data.info.attributionTags != null && data.info.attributionTags.length > 0) {
4470 final String attributionTag = data.info.attributionTags[0];
4471 context = (ContextImpl) context.createAttributionContext(attributionTag);
4472 }
4473 java.lang.ClassLoader cl = context.getClassLoader();
4474 data.intent.setExtrasClassLoader(cl);
4475 data.intent.prepareToEnterProcess(
4476 isProtectedComponent(data.info) || isProtectedBroadcast(data.intent),
4477 context.getAttributionSource());
4478 data.setExtrasClassLoader(cl);
4479 receiver = packageInfo.getAppFactory()
4480 .instantiateReceiver(cl, data.info.name, data.intent);
4481 } catch (Exception e) {
4482 if (DEBUG_BROADCAST) Slog.i(TAG,
4483 "Finishing failed broadcast to " + data.intent.getComponent());
4484 data.sendFinished(mgr);
4485 throw new RuntimeException(
4486 "Unable to instantiate receiver " + component
4487 + ": " + e.toString(), e);
4488 }
4489
4490 try {
4491 if (localLOGV) Slog.v(
4492 TAG, "Performing receive of " + data.intent
4493 + ": app=" + app
4494 + ", appName=" + app.getPackageName()
4495 + ", pkg=" + packageInfo.getPackageName()
4496 + ", comp=" + data.intent.getComponent().toShortString()
4497 + ", dir=" + packageInfo.getAppDir());
4498
4499 sCurrentBroadcastIntent.set(data.intent);
4500 receiver.setPendingResult(data);
4501
4502
4503 if (ZtePerformanceDebug.DEBUG_SYSTRACE_TAG
4504 && Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {
4505 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
4506 "receiver:" + receiver + ", intent=" + data.intent);
4507 }
4508
4509 receiver.onReceive(context.getReceiverRestrictedContext(),
4510 data.intent);
4511 } catch (Exception e) {
4512 if (DEBUG_BROADCAST) Slog.i(TAG,
4513 "Finishing failed broadcast to " + data.intent.getComponent());
4514 data.sendFinished(mgr);
4515 if (!mInstrumentation.onException(receiver, e)) {
4516 throw new RuntimeException(
4517 "Unable to start receiver " + component
4518 + ": " + e.toString(), e);
4519 }
4520 } finally {
4521 sCurrentBroadcastIntent.set(null);
4522 }
4523
4524 if (receiver.getPendingResult() != null) {
4525 data.finish();
4526 }
4527
4528
4529 if (ZtePerformanceDebug.DEBUG_SYSTRACE_TAG
4530 && Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {
4531 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
4532 }
4533
4534 }
注释1中,调用 LoadedApk 中的 makeApplication 方法:
1316 public Application makeApplication(boolean forceDefaultAppClass,
1317 Instrumentation instrumentation) {
1318 if (mApplication != null) {
1319 return mApplication;
1320 }
1321
1322 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "makeApplication");
1323
1324 Application app = null;
1325
1326 String appClass = mApplicationInfo.className;
1327 if (forceDefaultAppClass || (appClass == null)) {
1328 appClass = "android.app.Application";
1329 }
1330
1331 try {
1332 final java.lang.ClassLoader cl = getClassLoader();
1333 if (!mPackageName.equals("android")) {
1334 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
1335 "initializeJavaContextClassLoader");
1336 initializeJavaContextClassLoader();
1337 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1338 }
1339
1340
1341 SparseArray<String> packageIdentifiers = getAssets().getAssignedPackageIdentifiers(
1342 false, false);
1343 for (int i = 0, n = packageIdentifiers.size(); i < n; i++) {
1344 final int id = packageIdentifiers.keyAt(i);
1345 if (id == 0x01 || id == 0x7f) {
1346 continue;
1347 }
1348
1349 rewriteRValues(cl, packageIdentifiers.valueAt(i), id);
1350 }
1351
1352 ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
1353
1354
1355 NetworkSecurityConfigProvider.handleNewApplication(appContext);
1356 app = mActivityThread.mInstrumentation.newApplication(
1357 cl, appClass, appContext);
1358 appContext.setOuterContext(app);
1359 } catch (Exception e) {
1360 if (!mActivityThread.mInstrumentation.onException(app, e)) {
1361 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1362 throw new RuntimeException(
1363 "Unable to instantiate application " + appClass
1364 + " package " + mPackageName + ": " + e.toString(), e);
1365 }
1366 }
1367 mActivityThread.mAllApplications.add(app);
1368 mApplication = app;
1369
1370 if (instrumentation != null) {
1371 try {
1372 instrumentation.callApplicationOnCreate(app);
1373 } catch (Exception e) {
1374 if (!instrumentation.onException(app, e)) {
1375 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1376 throw new RuntimeException(
1377 "Unable to create application " + app.getClass().getName()
1378 + ": " + e.toString(), e);
1379 }
1380 }
1381 }
1382
1383 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1384
1385 return app;
1386 }
这里我们看看注释 3 处的 Application 是如何创建的, Instrumentation 的 newApplication 方法:
// frameworks/base/core/java/android/app/Instrumentation.java
1163 /**
1164 * Perform instantiation of the process's {@link Application} object. The
1165 * default implementation provides the normal system behavior.
1166 *
1167 * @param cl The ClassLoader with which to instantiate the object.
1168 * @param className The name of the class implementing the Application
1169 * object.
1170 * @param context The context to initialize the application with
1171 *
1172 * @return The newly instantiated Application object.
1173 */
1174 public Application newApplication(ClassLoader cl, String className, Context context)
1175 throws InstantiationException, IllegalAccessException,
1176 ClassNotFoundException {
1177 Application app = getFactory(context.getPackageName())
1178 .instantiateApplication(cl, className);
1179 app.attach(context);
1180 return app;
1181 }
1183 /**
1184 * Perform instantiation of the process's {@link Application} object. The
1185 * default implementation provides the normal system behavior.
1186 *
1187 * @param clazz The class used to create an Application object from.
1188 * @param context The context to initialize the application with
1189 *
1190 * @return The newly instantiated Application object.
1191 */
1192 static public Application newApplication(Class<?> clazz, Context context)
1193 throws InstantiationException, IllegalAccessException,
1194 ClassNotFoundException {
1195 Application app = (Application)clazz.newInstance();
1196 app.attach(context); // 1
1197 return app;
1198 }
Instrumentataion 中有两个 newApplication 重载方法,最终会调用上面这个方法。
注释1 处通过 反射来创建 Application ,并调用了 Application 的 attach 方法,将 ContextImpl 传进去,最后返回该 Application 的attach方法如下所示:
329 @UnsupportedAppUsage
330 final void attach(Context context) {
331 attachBaseContext(context);
332 mLoadedApk = ContextImpl.getImpl(context).mPackageInfo;
333 }
在attach 方法中调用了attachBaseContext 方法,他在 Application 的父类 ContextWrapper 中实现。
72
79 protected void attachBaseContext(Context base) {
80 if (mBase != null) {
81 throw new IllegalStateException("Base context already set");
82 }
83 mBase = base;
84 }
这个base 一路传递过来指的是 ContextImpl, 它是 Context 的实现类,将ContextImpl 赋值给 ContextWrapper 的 Context 类型的成员变量 mBase , 这样在 ContextWrapper 中就可以使用Context 的方法。
Application 的 attach 方法的作用就是使 Application 可以 Context 的方法,这样 Application 才可以用来代表 Application Context。
总结
android 12 的流程有变,但是很多地方并没有该,梳理流程如下:
[ActivityThread.java]
| scheduleReceiver()
| | sendMessage(H.RECEIVER, r)
| |
| H
| | handleMessage(Message msg)
| | handleReceiver((ReceiverData)msg.obj)
| | | app = packageInfo.makeApplication(false, mInstrumentation);
| | | |
| | | [LoadApk.java]
| | | | makeApplication
| | | | |
| | | | [Instrumentation.java]
| | | | | newApplication
| | | | | | app.attach(context)
| | | | | | |
| | | | | | [Application.java]
| | | | | | | attachBaseContext(context)
| | | | | | | |
| | | | | | | ContextWrapper
5.3 Application Context 的获取过程
上面我们知道了 Application Context 的创建,现在我们来看看它的获取。
这里主要通过调用 getApplicationContext 方法来获得 Application Context,该方法在 ContextWrapperer 中实现。
124 public Context getApplicationContext() {
125 return mBase.getApplicationContext();
126 }
127
这里 mBase 指的是 ContextImpl, 看看 ContextImpl 的 getApplicationContext 方法:
407 public Context getApplicationContext() {
408 return (mPackageInfo != null) ?
409 mPackageInfo.getApplication() : mMainThread.getApplication();
410 }
如果LoadedApk 类型的mPackageInfo 不为 null, 则调用 LoadedApk 的 getApplication 方法,否则调用 ActivityThread 的 getApplication 方法。由于应用程序已经启动,LoadedApk不会为 null ,则会调用 LoadApk 的 getApplication 方法。
// frameworks/base/core/java/android/app/LoadedApk.java
162 Application getApplication() {
163 return mApplication;
164 }
这里的 mApplication 在上文 LoadedApk 的 makeApplication 方法的注释5 处被赋值。
这样我们通过 getApplicationContext 方法就获取到了 Application Context.
5.4 Activity 的 Context 创建过程
想要在 Activity 中使用 Context 提供的方法,务必要先创建 Context。
Activity 的 Context 会在 Activity 的启动过程中被创建。
我们直接看看 ActivityThread 的 performLaunchActivity 方法:
3683 private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
3684 ActivityInfo aInfo = r.activityInfo;
3685 if (r.packageInfo == null) {
3686 r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
3687 Context.CONTEXT_INCLUDE_CODE);
3688 }
3689
3690 if (ZTE_TRAVERSAL_ACCELERATE_ENABLED) {
3691
3692 if (sIsAppFirstStartActivity) {
3693 sIsAppFirstStartActivity = false;
3694 if (r != null && r.intent != null) {
3695 String intentInfoStr = r.intent.toString();
3696 if (!(intentInfoStr != null && intentInfoStr.contains(Intent.ACTION_MAIN)
3697 && intentInfoStr.contains(Intent.CATEGORY_LAUNCHER))) {
3698
3699 sIsEnableAppTraversalsAccelerate = false;
3700 }
3701 }
3702 if (sIsEnableAppTraversalsAccelerate) {
3703 mH.removeCallbacks(mDisableAppTraversalsAccelerateRunnable);
3704 mH.postDelayed(mDisableAppTraversalsAccelerateRunnable, 3000);
3705 }
3706 }
3707
3708 }
3709 ComponentName component = r.intent.getComponent();
3710 if (component == null) {
3711 component = r.intent.resolveActivity(
3712 mInitialApplication.getPackageManager());
3713 r.intent.setComponent(component);
3714 }
3715
3716 if (r.activityInfo.targetActivity != null) {
3717 component = new ComponentName(r.activityInfo.packageName,
3718 r.activityInfo.targetActivity);
3719 }
3720
3721 ContextImpl appContext = createBaseContextForActivity(r);
3722 Activity activity = null;
3723 try {
3724 java.lang.ClassLoader cl = appContext.getClassLoader();
3725 activity = mInstrumentation.newActivity(
3726 cl, component.getClassName(), r.intent);
3727 StrictMode.incrementExpectedActivityCount(activity.getClass());
3728 r.intent.setExtrasClassLoader(cl);
3729 r.intent.prepareToEnterProcess(isProtectedComponent(r.activityInfo),
3730 appContext.getAttributionSource());
3731 if (r.state != null) {
3732 r.state.setClassLoader(cl);
3733 }
3734 } catch (Exception e) {
3735 if (!mInstrumentation.onException(activity, e)) {
3736 throw new RuntimeException(
3737 "Unable to instantiate activity " + component
3738 + ": " + e.toString(), e);
3739 }
3740 }
3741
3742 try {
3743 Application app = r.packageInfo.makeApplication(false, mInstrumentation);
3744
3745 if (localLOGV) Slog.v(TAG, "Performing launch of " + r);
3746 if (localLOGV) Slog.v(
3747 TAG, r + ": app=" + app
3748 + ", appName=" + app.getPackageName()
3749 + ", pkg=" + r.packageInfo.getPackageName()
3750 + ", comp=" + r.intent.getComponent().toShortString()
3751 + ", dir=" + r.packageInfo.getAppDir());
3752
3753 if (activity != null) {
3754 CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
3755 Configuration config =
3756 new Configuration(mConfigurationController.getCompatConfiguration());
3757 if (r.overrideConfig != null) {
3758 config.updateFrom(r.overrideConfig);
3759 }
3760 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "
3761 + r.activityInfo.name + " with config " + config);
3762 Window window = null;
3763 if (r.mPendingRemoveWindow != null && r.mPreserveWindow) {
3764 window = r.mPendingRemoveWindow;
3765 r.mPendingRemoveWindow = null;
3766 r.mPendingRemoveWindowManager = null;
3767 }
3768
3769
3770
3771 appContext.getResources().addLoaders(
3772 app.getResources().getLoaders().toArray(new ResourcesLoader[0]));
3773
3774 appContext.setOuterContext(activity);
3775 activity.attach(appContext, this, getInstrumentation(), r.token,
3776 r.ident, app, r.intent, r.activityInfo, title, r.parent,
3777 r.embeddedID, r.lastNonConfigurationInstances, config,
3778 r.referrer, r.voiceInteractor, window, r.configCallback,
3779 r.assistToken, r.shareableActivityToken);
3780
3781 if (customIntent != null) {
3782 activity.mIntent = customIntent;
3783 }
3784 r.lastNonConfigurationInstances = null;
3785 checkAndBlockForNetworkAccess();
3786 activity.mStartedActivity = false;
3787 int theme = r.activityInfo.getThemeResource();
3788 if (theme != 0) {
3789 activity.setTheme(theme);
3790 }
3791
3792 if (r.mActivityOptions != null) {
3793 activity.mPendingOptions = r.mActivityOptions;
3794 r.mActivityOptions = null;
3795 }
3796 activity.mLaunchedFromBubble = r.mLaunchedFromBubble;
3797 activity.mCalled = false;
3798 if (r.isPersistable()) {
3799 mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
3800 } else {
3801 mInstrumentation.callActivityOnCreate(activity, r.state);
3802 }
3803 if (!activity.mCalled) {
3804 throw new SuperNotCalledException(
3805 "Activity " + r.intent.getComponent().toShortString() +
3806 " did not call through to super.onCreate()");
3807 }
3808 r.activity = activity;
3809 mLastReportedWindowingMode.put(activity.getActivityToken(),
3810 config.windowConfiguration.getWindowingMode());
3811 }
3812 r.setState(ON_CREATE);
3813
3814
3815
3816
3817 synchronized (mResourcesManager) {
3818 mActivities.put(r.token, r);
3819 }
3820
3821 } catch (SuperNotCalledException e) {
3822 throw e;
3823
3824 } catch (Exception e) {
3825 if (!mInstrumentation.onException(activity, e)) {
3826 throw new RuntimeException(
3827 "Unable to start activity " + component
3828 + ": " + e.toString(), e);
3829 }
3830 }
3831
3832 return activity;
3833 }
这里单独说一下注释4处的 Activity 的 attach 方法:
final void attach(Context context, ActivityThread aThread,
8532 Instrumentation instr, IBinder token, int ident,
8533 Application application, Intent intent, ActivityInfo info,
8534 CharSequence title, Activity parent, String id,
8535 NonConfigurationInstances lastNonConfigurationInstances,
8536 Configuration config, String referrer, IVoiceInteractor voiceInteractor,
8537 Window window, ActivityConfigCallback activityConfigCallback, IBinder assistToken,
8538 IBinder shareableActivityToken) {
8539 attachBaseContext(context);
8540
8541 mFragments.attachHost(null );
8542
8543 mWindow = new PhoneWindow(this, window, activityConfigCallback);
8544 mWindow.setWindowControllerCallback(mWindowControllerCallback);
8545 mWindow.setCallback(this);
8546 mWindow.setOnWindowDismissedCallback(this);
8547 mWindow.getLayoutInflater().setPrivateFactory(this);
8548 if (info.softInputMode != WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED) {
8549 mWindow.setSoftInputMode(info.softInputMode);
8550 }
8551 if (info.uiOptions != 0) {
8552 mWindow.setUiOptions(info.uiOptions);
8553 }
8554 mUiThread = Thread.currentThread();
8555
8556 mMainThread = aThread;
8557 mInstrumentation = instr;
8558 mToken = token;
8559 mAssistToken = assistToken;
8560 mShareableActivityToken = shareableActivityToken;
8561 mIdent = ident;
8562 mApplication = application;
8563 mIntent = intent;
8564 mReferrer = referrer;
8565 mComponent = intent.getComponent();
8566 mActivityInfo = info;
8567 mTitle = title;
8568 mParent = parent;
8569 mEmbeddedID = id;
8570 mLastNonConfigurationInstances = lastNonConfigurationInstances;
8571 if (voiceInteractor != null) {
8572 if (lastNonConfigurationInstances != null) {
8573 mVoiceInteractor = lastNonConfigurationInstances.voiceInteractor;
8574 } else {
8575 mVoiceInteractor = new VoiceInteractor(voiceInteractor, this, this,
8576 Looper.myLooper());
8577 }
8578 }
8579
8580 mWindow.setWindowManager(
8581 (WindowManager)context.getSystemService(Context.WINDOW_SERVICE),
8582 mToken, mComponent.flattenToString(),
8583 (info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);
8584 if (mParent != null) {
8585 mWindow.setContainer(mParent.getWindow());
8586 }
8587 mWindowManager = mWindow.getWindowManager();
8588 mCurrentConfig = config;
8589
8590 mWindow.setColorMode(info.colorMode);
8591 mWindow.setPreferMinimalPostProcessing(
8592 (info.flags & ActivityInfo.FLAG_PREFER_MINIMAL_POST_PROCESSING) != 0);
8593
8594 setAutofillOptions(application.getAutofillOptions());
8595 setContentCaptureOptions(application.getContentCaptureOptions());
8596
8597 try {
8598 mClipboardManager = new ClipboardManager(context, null);
8599 } catch (Exception e) {
8600 Slog.w(TAG, "ClipboardManager get failed", e);
8601 }
8602
8603 }
注释1 处的 attachBaseContext 方法在 ContextThemeWrapper 中实现。
86 protected void attachBaseContext(Context newBase) {
87 super.attachBaseContext(newBase);
88 }
attachBaseContext 方法接着调用 ContextThemeWrapper 的父类 ContextWrapper 的 attachBaseContext 方法:
79 protected void attachBaseContext(Context base) {
80 if (mBase != null) {
81 throw new IllegalStateException("Base context already set");
82 }
83 mBase = base;
84 }
当我们调用ContextWrapper 的 getTheme 方法时,其实就是调用了 ContextImpl 的 getTheme 方法。
141 public Resources.Theme getTheme() {
142 return mBase.getTheme();
143 }
144
总结
在启动Activity 的过程中创建 ContextImpl , 并赋值给 ContextWrapper 的成员变量mBase。
Activity 继承自 ContextWrapper 的子类 ContextThemeWrapper, 这样在 Activity 中就可以使用 Context 中定义的方法了。
5.5 Service 的 Context 创建过程
Service 的Context 创建过程与 Activity 的 Context 创建过程类似,是在Service 的启动过程中被创建的。
ActivityThread 启动 Service
ActivityThread 的内部类 ApplicationThread 会调用 scheduleCreateService 方法来启动 Service.
1110 public final void scheduleCreateService(IBinder token,
1111 ServiceInfo info, CompatibilityInfo compatInfo, int processState) {
1112 updateProcessState(processState, false);
1113 CreateServiceData s = new CreateServiceData();
1114 s.token = token;
1115 s.info = info;
1116 s.compatInfo = compatInfo;
1117
1118 sendMessage(H.CREATE_SERVICE, s);
1119 }
1120
这里整体的流程和 Activity 的 Context 创建类似:
private void handleCreateService(CreateServiceData data) {
4658
4659
4660 unscheduleGcIdler();
4661
4662 LoadedApk packageInfo = getPackageInfoNoCheck(
4663 data.info.applicationInfo, data.compatInfo);
4664 Service service = null;
4665 try {
4666 if (localLOGV) Slog.v(TAG, "Creating service " + data.info.name);
4667
4668 Application app = packageInfo.makeApplication(false, mInstrumentation);
4669
4670 final java.lang.ClassLoader cl;
4671 if (data.info.splitName != null) {
4672 cl = packageInfo.getSplitClassLoader(data.info.splitName);
4673 } else {
4674 cl = packageInfo.getClassLoader();
4675 }
4676 service = packageInfo.getAppFactory()
4677 .instantiateService(cl, data.info.name, data.intent);
4678 ContextImpl context = ContextImpl.getImpl(service
4679 .createServiceBaseContext(this, packageInfo));
4680 if (data.info.splitName != null) {
4681 context = (ContextImpl) context.createContextForSplit(data.info.splitName);
4682 }
4683 if (data.info.attributionTags != null && data.info.attributionTags.length > 0) {
4684 final String attributionTag = data.info.attributionTags[0];
4685 context = (ContextImpl) context.createAttributionContext(attributionTag);
4686 }
4687
4688
4689 context.getResources().addLoaders(
4690 app.getResources().getLoaders().toArray(new ResourcesLoader[0]));
4691
4692 context.setOuterContext(service);
4693 service.attach(context, this, data.info.name, data.token, app,
4694 ActivityManager.getService());
4695
4696 if (ZtePerformanceDebug.DEBUG_SYSTRACE_TAG
4697 && Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {
4698 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "onCreate:" + service);
4699 }
4700
4701 service.onCreate();
4702 mServicesData.put(data.token, data);
4703 if (ZtePerformanceDebug.DEBUG_SYSTRACE_TAG
4704 && Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {
4705 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
4706 }
4707
4708 mServices.put(data.token, service);
4709 try {
4710 ActivityManager.getService().serviceDoneExecuting(
4711 data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
4712 } catch (RemoteException e) {
4713 throw e.rethrowFromSystemServer();
4714 }
4715 } catch (Exception e) {
4716 if (!mInstrumentation.onException(service, e)) {
4717 throw new RuntimeException(
4718 "Unable to create service " + data.info.name
4719 + ": " + e.toString(), e);
4720 }
4721 }
4722 }
4723
Y_MANAGER)) { 4705 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 4706 } 4707 //zte add end 4708 mServices.put(data.token, service); 4709 try { 4710 ActivityManager.getService().serviceDoneExecuting( 4711 data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0); 4712 } catch (RemoteException e) { 4713 throw e.rethrowFromSystemServer(); 4714 } 4715 } catch (Exception e) { 4716 if (!mInstrumentation.onException(service, e)) { 4717 throw new RuntimeException( 4718 "Unable to create service " + data.info.name 4719 + ": " + e.toString(), e); 4720 } 4721 } 4722 } 4723
|