Android应用的ClassLoader创建过程

来源:互联网 发布:他趣聊天软件 编辑:程序博客网 时间:2024/06/07 06:05

还是从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;    }}
原创粉丝点击