安卓高手之路之ClassLoader(四)

来源:互联网 发布:mac最好的视频播放器 编辑:程序博客网 时间:2024/06/06 12:47

显然,应用层的classLoader绝对不仅仅是一个systemclassloader那么简单。那么他一定是与PackageInfo连接起来的。而这个连接的纽带就是ContextImpl。ContextImpl又与apk一一对应。

    @Override    public ClassLoader getClassLoader() {        return mPackageInfo != null ?                mPackageInfo.getClassLoader() : ClassLoader.getSystemClassLoader();    }

 

 

 

    public ClassLoader getClassLoader() {        synchronized (this) {            if (mClassLoader != null) {                return mClassLoader;            }            if (mIncludeCode && !mPackageName.equals("android")) {                String zip = mAppDir;                /*                 * The following is a bit of a hack to inject                 * instrumentation into the system: If the app                 * being started matches one of the instrumentation names,                 * then we combine both the "instrumentation" and                 * "instrumented" app into the path, along with the                 * concatenation of both apps' shared library lists.                 */                String instrumentationAppDir =                        mActivityThread.mInstrumentationAppDir;                String instrumentationAppPackage =                        mActivityThread.mInstrumentationAppPackage;                String instrumentedAppDir =                        mActivityThread.mInstrumentedAppDir;                String[] instrumentationLibs = null;                if (mAppDir.equals(instrumentationAppDir)                        || mAppDir.equals(instrumentedAppDir)) {                    zip = instrumentationAppDir + ":" + instrumentedAppDir;                    if (! instrumentedAppDir.equals(instrumentationAppDir)) {                        instrumentationLibs =                            getLibrariesFor(instrumentationAppPackage);                    }                }                if ((mSharedLibraries != null) ||                        (instrumentationLibs != null)) {                    zip =                        combineLibs(mSharedLibraries, instrumentationLibs)                        + ':' + zip;                }                /*                 * With all the combination done (if necessary, actually                 * create the class loader.                 */                if (ActivityThread.localLOGV)                    Slog.v(ActivityThread.TAG, "Class path: " + zip + ", JNI path: " + mLibDir);                // Temporarily disable logging of disk reads on the Looper thread                // as this is early and necessary.                StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();                mClassLoader =                    ApplicationLoaders.getDefault().getClassLoader(                        zip, mLibDir, mBaseClassLoader);                initializeJavaContextClassLoader();                StrictMode.setThreadPolicy(oldPolicy);            } else {                if (mBaseClassLoader == null) {                    mClassLoader = ClassLoader.getSystemClassLoader();                } else {                    mClassLoader = mBaseClassLoader;                }            }            return mClassLoader;        }    }

 

 mClassLoader =                    ApplicationLoaders.getDefault().getClassLoader(                        zip, mLibDir, mBaseClassLoader);

 

 /* * Copyright (C) 2006 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * *      http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package android.app;import dalvik.system.PathClassLoader;import java.util.HashMap;import java.util.Map;class ApplicationLoaders{    public static ApplicationLoaders getDefault()    {        return gApplicationLoaders;    }    public ClassLoader getClassLoader(String zip, String libPath, ClassLoader parent)    {        /*         * This is the parent we use if they pass "null" in.  In theory         * this should be the "system" class loader; in practice we         * don't use that and can happily (and more efficiently) use the         * bootstrap class loader.         */        ClassLoader baseParent = ClassLoader.getSystemClassLoader().getParent();        synchronized (mLoaders) {            if (parent == null) {                parent = baseParent;            }            /*             * If we're one step up from the base class loader, find             * something in our cache.  Otherwise, we create a whole             * new ClassLoader for the zip archive.             */            if (parent == baseParent) {                ClassLoader loader = mLoaders.get(zip);                if (loader != null) {                    return loader;                }                    PathClassLoader pathClassloader =                    new PathClassLoader(zip, libPath, parent);                                mLoaders.put(zip, pathClassloader);                return pathClassloader;            }            return new PathClassLoader(zip, parent);        }    }    private final Map<String, ClassLoader> mLoaders = new HashMap<String, ClassLoader>();    private static final ApplicationLoaders gApplicationLoaders        = new ApplicationLoaders();}

 

 所有的东西都在这里。具体不多说了。看了就明白。

还有一个活动当前调用的classLoader。如下:

 

static void Dalvik_dalvik_system_VMStack_getCallingClassLoader(const u4* args,    JValue* pResult){    ClassObject* clazz =        dvmGetCaller2Class(dvmThreadSelf()->interpSave.curFrame);    UNUSED_PARAMETER(args);    if (clazz == NULL)        RETURN_PTR(NULL);    RETURN_PTR(clazz->classLoader);}

 java层为VMStack.java

 

  native public static ClassLoader getCallingClassLoader();

 可以直接认为是加载当前类的classLoader。如果是BootClassLoader,那么就返回null

原创粉丝点击