1、Activity的Context创建过程
Context是在Activity的启动过程中创建的,这里就从Activity的启动开始分析。Activity的启动会调用ActivityThread
的内部类ApplicationThread
的scheduleLaunchActivity()
,我们就从这个方法开始。
ApplicationThread##scheduleLaunchActivity()
@Override
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;
...
sendMessage(H.LAUNCH_ACTIVITY, r);
}
scheduleLaunchActivity
方法会将启动Activity的参数封装成ActivityClientRecord
,sendMessage
方法向H类发送类型为LAUNCH_ACTIVITY
的消息,并将ActivityClientRecord
传递过去。sendMessage
方法的目的是将启动Activity的逻辑放在主线程中的消息队列中,这样启动Activity的逻辑就会在主线程中执行。
H类的handleMessage
方法中会对LAUNCH_ACTIVITY
类型的消息进行处理,其中调用了handleLaunchActivity
方法
ActivityThread##handleLaunchActivity()
@Override
public Activity handleLaunchActivity(ActivityClientRecord r,
PendingTransactionActions pendingActions, Intent customIntent) {
//...
final Activity a = performLaunchActivity(r, customIntent);
//...
return a;
}
里面调用了performLaunchActivity()
,继续往下跟
ActivityThread##performLaunchActivity()
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);
}
//创建Activity的Context
ContextImpl appContext = createBaseContextForActivity(r);
Activity activity = null;
try {
java.lang.ClassLoader cl = appContext.getClassLoader();
//创建Activity,内部通过反射创建的
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
//....
} catch (Exception e) {
//....
}
try {
//.....
if (activity != null) {
//将Activity赋值给ContextImpl中的mOuterContext
appContext.setOuterContext(activity);
//调用Activity的attach()方法
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, r.configCallback);
//调用Activity的onCreate()
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
}
//....
}
//....
return activity;
}
方法中逻辑比较负责,这里只保留了Activity的Context创建的相关代码,代码中已经做了注释,这里主要看下activity.attach()
Activity##attach()
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, ActivityConfigCallback activityConfigCallback) {
//调用其父类ContextWrapper,将创建的ContextImpl传递给mBase
attachBaseContext(context);
//创建Window
mWindow = new PhoneWindow(this, window, activityConfigCallback);
//设置回调,PhoneWindow中的点击事件、按键事件、滑动事件通过callBack传递给Activity
mWindow.setCallback(this);
//...
//给Window设置WindowManager
mWindow.setWindowManager(
(WindowManager)context.getSystemService(Context.WINDOW_SERVICE),
mToken, mComponent.flattenToString(),
(info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);
//将WindowManager赋值给Activity的成员变量,所以在Activity中可以直接调用getWindowManager()来获取WindowManager
mWindowManager = mWindow.getWindowManager();
//....
}
这里主要看下attachBaseContext(context)
,它的实现在ContextWrapper
中
ContextWrapper##attachBaseContext(context)
protected void attachBaseContext(Context base) {
if (mBase != null) {
throw new IllegalStateException("Base context already set");
}
mBase = base;
}
和Application Context一样,Activity Context创建完成后会一直传递给ContextImpl
的mBase
。这样ContextWrapper
的处理就可以交由Contextimpl
来处理了。至此Activity的Context创建流程就结束了,下面总结一下:
![](https://img.haomeiwen.com/i7264052/543ddcd9e2e67fe8.png)
2、Service Context创建流程
和Activity Context创建流程类似,Service
的创建是在ActivityThread
的内部类ApplicationThread
的scheduleCreateService()
。
ApplicationThread##scheduleCreateService()
public final void scheduleCreateService(IBinder token,
ServiceInfo info, CompatibilityInfo compatInfo, int processState) {
...
sendMessage(H.CREATE_SERVICE, s);
}
在ApplicationThread
中向H
发送H.CREATE_SERVICE
类型的消息,在handleMessage()
中会调用ActivityThread.handleCreateService()
ActivityThread##handleCreateService()
private void handleCreateService(CreateServiceData data) {
//....
LoadedApk packageInfo = getPackageInfoNoCheck(
data.info.applicationInfo, data.compatInfo);
Service service = null;
try {
java.lang.ClassLoader cl = packageInfo.getClassLoader();
//创建Service 内部使用反射创建
service = packageInfo.getAppFactory()
.instantiateService(cl, data.info.name, data.intent);
} catch (Exception e) {
//.....
}
try {
//创建ContextImpl
ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
context.setOuterContext(service);
Application app = packageInfo.makeApplication(false, mInstrumentation);
//调用Service的attach()
service.attach(context, this, data.info.name, data.token, app,
ActivityManager.getService());
//调用Service的onCreate()
service.onCreate();
mServices.put(data.token, service);
//....
} catch (Exception e) {
//.....
}
}
该方法中创建了Service
和ContextImpl
并调用了Service.attach()
Service##attach()
public final void attach(
Context context,
ActivityThread thread, String className, IBinder token,
Application application, Object activityManager) {
attachBaseContext(context);
mThread = thread; // NOTE: unused - remove?
mClassName = className;
mToken = token;
mApplication = application;
mActivityManager = (IActivityManager)activityManager;
mStartCompatibility = getApplicationInfo().targetSdkVersion
< Build.VERSION_CODES.ECLAIR;
}
在attach()
中调用attachBaseContext(context)
,attachBaseContext(context)
的具体实现是在ContextWrapper
ContextWrapper##attachBaseContext()
protected void attachBaseContext(Context base) {
if (mBase != null) {
throw new IllegalStateException("Base context already set");
}
mBase = base;
}
可以看到最终将创建的ContextImpl传递给ContextWrapper
的mBase。
网友评论