还是从Application的创建说起
/frameworks/base/core/java/android/app/ActivityThread.java
private void handleBindApplication(AppBindData data) {
data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);
LoadedApk pi = getPackageInfo(instrApp, data.compatInfo,
appContext.getClassLoader(), false, true, false);
// 1、创建Context
ContextImpl instrContext = ContextImpl.createAppContext(this, pi);
// 2、获取类加载器
java.lang.ClassLoader cl = instrContext.getClassLoader();
mInstrumentation = (Instrumentation)
cl.loadClass(data.instrumentationName.getClassName()).newInstance();
Application app = data.info.makeApplication(data.restrictedBackupMode, null);
mInitialApplication = app;
mInstrumentation.callApplicationOnCreate(app);
}
1、创建Context
static ContextImpl createAppContext(ActivityThread mainThread, LoadedApk packageInfo) {
if (packageInfo == null) throw new IllegalArgumentException("packageInfo");
// 直接创建一个ContextImpl对象
return new ContextImpl(null, mainThread,
packageInfo, null, null, false, null, null);
}
/frameworks/base/core/java/android/app/ContextImpl.java
private ContextImpl(ContextImpl container, ActivityThread mainThread,
LoadedApk packageInfo, IBinder activityToken, UserHandle user, boolean restricted,
Display display, Configuration overrideConfiguration) {
mOuterContext = this;
mMainThread = mainThread;
mActivityToken = activityToken;
mRestricted = restricted;
if (user == null) {
user = Process.myUserHandle();
}
mUser = user;
// ContextImpl的mPackageInfo存放有对应的LoadedApk对象
mPackageInfo = packageInfo;
mResourcesManager = ResourcesManager.getInstance();
mDisplay = display;
mOverrideConfiguration = overrideConfiguration;
final int displayId = getDisplayId();
CompatibilityInfo compatInfo = null;
if (container != null) {
compatInfo = container.getDisplayAdjustments(displayId).getCompatibilityInfo();
}
if (compatInfo == null && displayId == Display.DEFAULT_DISPLAY) {
compatInfo = packageInfo.getCompatibilityInfo();
}
mDisplayAdjustments.setCompatibilityInfo(compatInfo);
mDisplayAdjustments.setActivityToken(activityToken);
Resources resources = packageInfo.getResources(mainThread);
if (resources != null) {
if (activityToken != null
|| displayId != Display.DEFAULT_DISPLAY
|| overrideConfiguration != null
|| (compatInfo != null && compatInfo.applicationScale
!= resources.getCompatibilityInfo().applicationScale)) {
resources = mResourcesManager.getTopLevelResources(packageInfo.getResDir(),
packageInfo.getSplitResDirs(), packageInfo.getOverlayDirs(),
packageInfo.getApplicationInfo().sharedLibraryFiles, displayId,
overrideConfiguration, compatInfo, activityToken);
}
}
mResources = resources;
if (container != null) {
mBasePackageName = container.mBasePackageName;
mOpPackageName = container.mOpPackageName;
} else {
mBasePackageName = packageInfo.mPackageName;
ApplicationInfo ainfo = packageInfo.getApplicationInfo();
if (ainfo.uid == Process.SYSTEM_UID && ainfo.uid != Process.myUid()) {
// Special case: system components allow themselves to be loaded in to other
// processes. For purposes of app ops, we must then consider the context as
// belonging to the package of this process, not the system itself, otherwise
// the package+uid verifications in app ops will fail.
mOpPackageName = ActivityThread.currentPackageName();
} else {
mOpPackageName = mBasePackageName;
}
}
mContentResolver = new ApplicationContentResolver(this, mainThread, user);
}
2、获取类加载器
/frameworks/base/core/java/android/app/ContextImpl.java
@Override
public ClassLoader getClassLoader() {
// 前面说过mPackageInfo存放有对应的LoadedApk对象
return mPackageInfo != null ?
mPackageInfo.getClassLoader() : ClassLoader.getSystemClassLoader();
}
/frameworks/base/core/java/android/app/LoadedApk.java
public ClassLoader getClassLoader() {
synchronized (this) {
if (mClassLoader != null) {
return mClassLoader;
}
// 调用ApplicationLoaders的getClassLoader方法
mClassLoader = ApplicationLoaders.getDefault().getClassLoader(zip, lib,
mBaseClassLoader);
return mClassLoader;
}
}
/frameworks/base/core/java/android/app/ApplicationLoaders.java
public ClassLoader getClassLoader(String zip, String libPath, ClassLoader parent)
{
ClassLoader baseParent = ClassLoader.getSystemClassLoader().getParent();
synchronized (mLoaders) {
if (parent == null) {
parent = baseParent;
// ClassLoader会被缓存在mLoaders中,也就是说它也是只会创建一次
if (parent == baseParent) {
ClassLoader loader = mLoaders.get(zip);
if (loader != null) {
return loader;
}
// 如果缓存中没有,就会创建一个PathClassLoader来对应用进行加载
PathClassLoader pathClassloader =
new PathClassLoader(zip, libPath, parent);
mLoaders.put(zip, pathClassloader);
return pathClassloader;
}
return pathClassloader;
}
}