zoukankan      html  css  js  c++  java
  • 安卓高手之路之ClassLoader(四)

    安卓高手之路之ClassLoader(四) - 修补C++ - ITeye技术网站

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

    Java代码  收藏代码
    1. @Override  
    2. public ClassLoader getClassLoader() {  
    3.     return mPackageInfo != null ?  
    4.             mPackageInfo.getClassLoader() : ClassLoader.getSystemClassLoader();  
    5. }  
        @Override
        public ClassLoader getClassLoader() {
            return mPackageInfo != null ?
                    mPackageInfo.getClassLoader() : ClassLoader.getSystemClassLoader();
        }
    
    Java代码  收藏代码
    1. public ClassLoader getClassLoader() {  
    2.     synchronized (this) {  
    3.         if (mClassLoader != null) {  
    4.             return mClassLoader;  
    5.         }  
    6.   
    7.         if (mIncludeCode && !mPackageName.equals("android")) {  
    8.             String zip = mAppDir;  
    9.   
    10.             /* 
    11.              * The following is a bit of a hack to inject 
    12.              * instrumentation into the system: If the app 
    13.              * being started matches one of the instrumentation names, 
    14.              * then we combine both the "instrumentation" and 
    15.              * "instrumented" app into the path, along with the 
    16.              * concatenation of both apps' shared library lists. 
    17.              */  
    18.   
    19.             String instrumentationAppDir =  
    20.                     mActivityThread.mInstrumentationAppDir;  
    21.             String instrumentationAppPackage =  
    22.                     mActivityThread.mInstrumentationAppPackage;  
    23.             String instrumentedAppDir =  
    24.                     mActivityThread.mInstrumentedAppDir;  
    25.             String[] instrumentationLibs = null;  
    26.   
    27.             if (mAppDir.equals(instrumentationAppDir)  
    28.                     || mAppDir.equals(instrumentedAppDir)) {  
    29.                 zip = instrumentationAppDir + ":" + instrumentedAppDir;  
    30.                 if (! instrumentedAppDir.equals(instrumentationAppDir)) {  
    31.                     instrumentationLibs =  
    32.                         getLibrariesFor(instrumentationAppPackage);  
    33.                 }  
    34.             }  
    35.   
    36.             if ((mSharedLibraries != null) ||  
    37.                     (instrumentationLibs != null)) {  
    38.                 zip =  
    39.                     combineLibs(mSharedLibraries, instrumentationLibs)  
    40.                     + ':' + zip;  
    41.             }  
    42.   
    43.             /* 
    44.              * With all the combination done (if necessary, actually 
    45.              * create the class loader. 
    46.              */  
    47.   
    48.             if (ActivityThread.localLOGV)  
    49.                 Slog.v(ActivityThread.TAG, "Class path: " + zip + ", JNI path: " + mLibDir);  
    50.   
    51.             // Temporarily disable logging of disk reads on the Looper thread  
    52.             // as this is early and necessary.  
    53.             StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();  
    54.   
    55.             mClassLoader =  
    56.                 ApplicationLoaders.getDefault().getClassLoader(  
    57.                     zip, mLibDir, mBaseClassLoader);  
    58.             initializeJavaContextClassLoader();  
    59.   
    60.             StrictMode.setThreadPolicy(oldPolicy);  
    61.         } else {  
    62.             if (mBaseClassLoader == null) {  
    63.                 mClassLoader = ClassLoader.getSystemClassLoader();  
    64.             } else {  
    65.                 mClassLoader = mBaseClassLoader;  
    66.             }  
    67.         }  
    68.         return mClassLoader;  
    69.     }  
    70. }  
        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;
            }
        }
    Java代码  收藏代码
    1. mClassLoader =  
    2.                    ApplicationLoaders.getDefault().getClassLoader(  
    3.                        zip, mLibDir, mBaseClassLoader);  
     mClassLoader =
                        ApplicationLoaders.getDefault().getClassLoader(
                            zip, mLibDir, mBaseClassLoader);
    Java代码  收藏代码
    1.  /* 
    2.  * Copyright (C) 2006 The Android Open Source Project 
    3.  * 
    4.  * Licensed under the Apache License, Version 2.0 (the "License"); 
    5.  * you may not use this file except in compliance with the License. 
    6.  * You may obtain a copy of the License at 
    7.  * 
    8.  *      http://www.apache.org/licenses/LICENSE-2.0 
    9.  * 
    10.  * Unless required by applicable law or agreed to in writing, software 
    11.  * distributed under the License is distributed on an "AS IS" BASIS, 
    12.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
    13.  * See the License for the specific language governing permissions and 
    14.  * limitations under the License. 
    15.  */  
    16.   
    17.   
    18. package android.app;  
    19.   
    20. import dalvik.system.PathClassLoader;  
    21.   
    22. import java.util.HashMap;  
    23. import java.util.Map;  
    24.   
    25. class ApplicationLoaders  
    26. {  
    27.     public static ApplicationLoaders getDefault()  
    28.     {  
    29.         return gApplicationLoaders;  
    30.     }  
    31.   
    32.     public ClassLoader getClassLoader(String zip, String libPath, ClassLoader parent)  
    33.     {  
    34.         /* 
    35.          * This is the parent we use if they pass "null" in.  In theory 
    36.          * this should be the "system" class loader; in practice we 
    37.          * don't use that and can happily (and more efficiently) use the 
    38.          * bootstrap class loader. 
    39.          */  
    40.         ClassLoader baseParent = ClassLoader.getSystemClassLoader().getParent();  
    41.   
    42.         synchronized (mLoaders) {  
    43.             if (parent == null) {  
    44.                 parent = baseParent;  
    45.             }  
    46.   
    47.             /* 
    48.              * If we're one step up from the base class loader, find 
    49.              * something in our cache.  Otherwise, we create a whole 
    50.              * new ClassLoader for the zip archive. 
    51.              */  
    52.             if (parent == baseParent) {  
    53.                 ClassLoader loader = mLoaders.get(zip);  
    54.                 if (loader != null) {  
    55.                     return loader;  
    56.                 }  
    57.       
    58.                 PathClassLoader pathClassloader =  
    59.                     new PathClassLoader(zip, libPath, parent);  
    60.                   
    61.                 mLoaders.put(zip, pathClassloader);  
    62.                 return pathClassloader;  
    63.             }  
    64.   
    65.             return new PathClassLoader(zip, parent);  
    66.         }  
    67.     }  
    68.   
    69.     private final Map<String, ClassLoader> mLoaders = new HashMap<String, ClassLoader>();  
    70.   
    71.     private static final ApplicationLoaders gApplicationLoaders  
    72.         = new ApplicationLoaders();  
    73. }  
     /*
     * 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。如下:

    Java代码  收藏代码
    1. static void Dalvik_dalvik_system_VMStack_getCallingClassLoader(const u4* args,  
    2.     JValue* pResult)  
    3. {  
    4.     ClassObject* clazz =  
    5.         dvmGetCaller2Class(dvmThreadSelf()->interpSave.curFrame);  
    6.   
    7.     UNUSED_PARAMETER(args);  
    8.   
    9.     if (clazz == NULL)  
    10.         RETURN_PTR(NULL);  
    11.     RETURN_PTR(clazz->classLoader);  
    12. }  
    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

    Java代码  收藏代码
    1. native public static ClassLoader getCallingClassLoader();  
      native public static ClassLoader getCallingClassLoader();

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

  • 相关阅读:
    操作系统---学习笔记00
    操作系统---学习笔记0
    2015/07/16入园啦!
    1-1 console的用法
    2.3 js基础--DOM
    1.2 js基础
    1.1 js基础
    信息收集(1)
    Android概述
    从一次失败的比赛经历引发的思考
  • 原文地址:https://www.cnblogs.com/seven1979/p/4369602.html
Copyright © 2011-2022 走看看