美文网首页
Android类加载器

Android类加载器

作者: TomyZhang | 来源:发表于2019-09-17 18:27 被阅读0次

    一、概念

    Android类加载器继承结构
    //测试代码
    public class MainActivity extends Activity {
        private static final String TAG = "HostClass";
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            ClassLoader classLoader = getClassLoader();
            while(classLoader != null) {
                Log.d(TAG, "zwm, classLoader: " + classLoader);
                classLoader = classLoader.getParent();
            }
        }
    }
    
    //输出log
    2019-09-17 17:37:20.011 HostClass: zwm, classLoader: dalvik.system.PathClassLoader[DexPathList[[zip file "/system/framework/org.apache.http.legacy.boot.jar", zip file "/data/app/com.tomorrow.testnetworkcache-j4o6HDFZgDbT5r_1CQiv4Q==/base.apk", zip file "/data/app/com.tomorrow.testnetworkcache-j4o6HDFZgDbT5r_1CQiv4Q==/split_lib_dependencies_apk.apk", zip file "/data/app/com.tomorrow.testnetworkcache-j4o6HDFZgDbT5r_1CQiv4Q==/split_lib_resources_apk.apk", zip file "/data/app/com.tomorrow.testnetworkcache-j4o6HDFZgDbT5r_1CQiv4Q==/split_lib_slice_0_apk.apk", zip file "/data/app/com.tomorrow.testnetworkcache-j4o6HDFZgDbT5r_1CQiv4Q==/split_lib_slice_1_apk.apk", zip file "/data/app/com.tomorrow.testnetworkcache-j4o6HDFZgDbT5r_1CQiv4Q==/split_lib_slice_2_apk.apk", zip file "/data/app/com.tomorrow.testnetworkcache-j4o6HDFZgDbT5r_1CQiv4Q==/split_lib_slice_3_apk.apk", zip file "/data/app/com.tomorrow.testnetworkcache-j4o6HDFZgDbT5r_1CQiv4Q==/split_lib_slice_4_apk.apk", zip file "/data/app/com.tomorrow.testnetworkcache-j4o6HDFZgDbT5r_1CQiv4Q==/split_lib_slice_5_apk.apk", zip file "/data/app/com.tomorrow.testnetworkcache-j4o6HDFZgDbT5r_1CQiv4Q==/split_lib_slice_6_apk.apk", zip file "/data/app/com.tomorrow.testnetworkcache-j4o6HDFZgDbT5r_1CQiv4Q==/split_lib_slice_7_apk.apk", zip file "/data/app/com.tomorrow.testnetworkcache-j4o6HDFZgDbT5r_1CQiv4Q==/split_lib_slice_8_apk.apk", zip file "/data/app/com.tomorrow.testnetworkcache-j4o6HDFZgDbT5r_1CQiv4Q==/split_lib_slice_9_apk.apk"],nativeLibraryDirectories=[/data/app/com.tomorrow.testnetworkcache-j4o6HDFZgDbT5r_1CQiv4Q==/lib/arm64, /system/lib64, /system/vendor/lib64]]]
    2019-09-17 17:37:20.012 HostClass: zwm, classLoader: java.lang.BootClassLoader@5bac62b
    

    二、Android类加载器

    BootClassLoader

    BootClassLoader实例在Android系统启动的时候被创建,用于加载一些Android系统框架的类,其中就包括APP用到的一些系统类。

    PathClassLoader

    PathClassLoader简单实现了ClassLoader,可以操作本地文件系统的文件和目录,但是不能从网络中加载类。Android使用PathClassLoader作为系统类加载器和应用程序类加载器。

    例子:(三星G9500,P OS)

    //步骤1.创建一个插件apk工程module:plugin,并创建一个插件类PluginClass,代码如下:
    public class PluginClass {
        private static final String TAG = "PluginClass";
    
        public void method() {
            Log.d(TAG, "zwm, this is plugin method");
        }
    }
    
    //步骤2.生成插件apk:plugin-debug.apk,并放到手机根目录
    
    //步骤3.创建一个宿主apk工程module:app,其中MainActivity代码如下:
    (需要在manifest中添加权限:<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>)
    public class MainActivity extends Activity {
        private static final String TAG = "HostClass";
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            String apkPath = Environment.getExternalStorageDirectory() + "/plugin-debug.apk";
            Log.d(TAG, "zwm, apkPath: " + apkPath);
            File file = new File(apkPath);
            if(!file.exists()) {
                Log.d(TAG, "zwm, file not exist");
                return;
            }
            loadApk(apkPath);
        }
    
        public  void loadApk(String apkPath) {
            Log.d(TAG, "zwm, loadApk, apkPath: " + apkPath);
            Log.d(TAG, "zwm, getClassLoader: " + getClassLoader()); //默认ClassLoader
            PathClassLoader classLoader = new PathClassLoader(apkPath, null, getClassLoader()); //使用PathClassLoader
            Log.d(TAG, "zwm, classLoader: " + classLoader);
            try {
                Class<?> pluginClass = classLoader.loadClass("com.tomorrow.plugin.PluginClass");
                Log.d(TAG, "zwm, pluginClass: " + pluginClass);
                Object pluginInstance = pluginClass.newInstance();
                Log.d(TAG, "zwm, pluginInstance: " + pluginInstance);
                Method pluginMethod = pluginClass.getMethod("method");
                Log.d(TAG, "zwm, call pluginMethod: " + pluginMethod);
                pluginMethod.invoke(pluginInstance);
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            } catch (InstantiationException e) {
                e.printStackTrace();
            }
        }
    }
    
    //步骤4.运行宿主apk,输出log如下:
    2019-09-16 16:36:41.124 HostClass: zwm, apkPath: /storage/emulated/0/plugin-debug.apk
    2019-09-16 16:36:41.124 HostClass: zwm, loadApk, apkPath: /storage/emulated/0/plugin-debug.apk
    2019-09-16 16:36:41.126 HostClass: zwm, getClassLoader: dalvik.system.PathClassLoader[DexPathList[[zip file "/system/framework/org.apache.http.legacy.boot.jar", zip file "/data/app/com.tomorrow.testnetworkcache-wKIVL_VnX2pjCS0Wz3-UsQ==/base.apk", zip file "/data/app/com.tomorrow.testnetworkcache-wKIVL_VnX2pjCS0Wz3-UsQ==/split_lib_dependencies_apk.apk", zip file "/data/app/com.tomorrow.testnetworkcache-wKIVL_VnX2pjCS0Wz3-UsQ==/split_lib_resources_apk.apk", zip file "/data/app/com.tomorrow.testnetworkcache-wKIVL_VnX2pjCS0Wz3-UsQ==/split_lib_slice_0_apk.apk", zip file "/data/app/com.tomorrow.testnetworkcache-wKIVL_VnX2pjCS0Wz3-UsQ==/split_lib_slice_1_apk.apk", zip file "/data/app/com.tomorrow.testnetworkcache-wKIVL_VnX2pjCS0Wz3-UsQ==/split_lib_slice_2_apk.apk", zip file "/data/app/com.tomorrow.testnetworkcache-wKIVL_VnX2pjCS0Wz3-UsQ==/split_lib_slice_3_apk.apk", zip file "/data/app/com.tomorrow.testnetworkcache-wKIVL_VnX2pjCS0Wz3-UsQ==/split_lib_slice_4_apk.apk", zip file "/data/app/com.tomorrow.testnetworkcache-wKIVL_VnX2pjCS0Wz3-UsQ==/split_lib_slice_5_apk.apk", zip file "/data/app/com.tomorrow.testnetworkcache-wKIVL_VnX2pjCS0Wz3-UsQ==/split_lib_slice_6_apk.apk", zip file "/data/app/com.tomorrow.testnetworkcache-wKIVL_VnX2pjCS0Wz3-UsQ==/split_lib_slice_7_apk.apk", zip file "/data/app/com.tomorrow.testnetworkcache-wKIVL_VnX2pjCS0Wz3-UsQ==/split_lib_slice_8_apk.apk", zip file "/data/app/com.tomorrow.testnetworkcache-wKIVL_VnX2pjCS0Wz3-UsQ==/split_lib_slice_9_apk.apk"],nativeLibraryDirectories=[/data/app/com.tomorrow.testnetworkcache-wKIVL_VnX2pjCS0Wz3-UsQ==/lib/arm64, /system/lib64, /system/vendor/lib64]]]
    2019-09-16 16:36:41.137 HostClass: zwm, classLoader: dalvik.system.PathClassLoader[DexPathList[[zip file "/storage/emulated/0/plugin-debug.apk"],nativeLibraryDirectories=[/system/lib64, /system/vendor/lib64]]]
    2019-09-16 16:36:41.137 HostClass: zwm, pluginClass: class com.tomorrow.plugin.PluginClass
    2019-09-16 16:36:41.137 HostClass: zwm, pluginInstance: com.tomorrow.plugin.PluginClass@957f597
    2019-09-16 16:36:41.138 HostClass: zwm, call pluginMethod: public void com.tomorrow.plugin.PluginClass.method()
    2019-09-16 16:36:41.138 PluginClass: zwm, this is plugin method
    

    DexClassLoader

    例子:(三星G9500,P OS)

    //步骤1.创建一个插件apk工程module:plugin,并创建一个插件类PluginClass,代码如下:
    public class PluginClass {
        private static final String TAG = "PluginClass";
    
        public void method() {
            Log.d(TAG, "zwm, this is plugin method");
        }
    }
    
    //步骤2.生成插件apk:plugin-debug.apk,并放到手机根目录
    
    //步骤3.创建一个宿主apk工程module:app,其中MainActivity代码如下:
    (需要在manifest中添加权限:<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>)
    public class MainActivity extends Activity {
        private static final String TAG = "HostClass";
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            String apkPath = Environment.getExternalStorageDirectory() + "/plugin-debug.apk";
            Log.d(TAG, "zwm, apkPath: " + apkPath);
            File file = new File(apkPath);
            if(!file.exists()) {
                Log.d(TAG, "zwm, file not exist");
                return;
            }
            loadApk(apkPath);
        }
    
        public  void loadApk(String apkPath) {
            Log.d(TAG, "zwm, loadApk, apkPath: " + apkPath);
            Log.d(TAG, "zwm, getClassLoader: " + getClassLoader()); //默认ClassLoader
            DexClassLoader classLoader = new DexClassLoader(apkPath, null, null, getClassLoader()); //使用DexClassLoader
            Log.d(TAG, "zwm, classLoader: " + classLoader);
            try {
                Class<?> pluginClass = classLoader.loadClass("com.tomorrow.plugin.PluginClass");
                Log.d(TAG, "zwm, pluginClass: " + pluginClass);
                Object pluginInstance = pluginClass.newInstance();
                Log.d(TAG, "zwm, pluginInstance: " + pluginInstance);
                Method pluginMethod = pluginClass.getMethod("method");
                Log.d(TAG, "zwm, call pluginMethod: " + pluginMethod);
                pluginMethod.invoke(pluginInstance);
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            } catch (InstantiationException e) {
                e.printStackTrace();
            }
        }
    }
    
    //步骤4.运行宿主apk,输出log如下:
    2019-09-16 16:31:05.076 HostClass: zwm, apkPath: /storage/emulated/0/plugin-debug.apk
    2019-09-16 16:31:05.077 HostClass: zwm, loadApk, apkPath: /storage/emulated/0/plugin-debug.apk
    2019-09-16 16:31:05.078 HostClass: zwm, getClassLoader: dalvik.system.PathClassLoader[DexPathList[[zip file "/system/framework/org.apache.http.legacy.boot.jar", zip file "/data/app/com.tomorrow.testnetworkcache-e0beKJuiJ-N2H6sE1CRjSw==/base.apk", zip file "/data/app/com.tomorrow.testnetworkcache-e0beKJuiJ-N2H6sE1CRjSw==/split_lib_dependencies_apk.apk", zip file "/data/app/com.tomorrow.testnetworkcache-e0beKJuiJ-N2H6sE1CRjSw==/split_lib_resources_apk.apk", zip file "/data/app/com.tomorrow.testnetworkcache-e0beKJuiJ-N2H6sE1CRjSw==/split_lib_slice_0_apk.apk", zip file "/data/app/com.tomorrow.testnetworkcache-e0beKJuiJ-N2H6sE1CRjSw==/split_lib_slice_1_apk.apk", zip file "/data/app/com.tomorrow.testnetworkcache-e0beKJuiJ-N2H6sE1CRjSw==/split_lib_slice_2_apk.apk", zip file "/data/app/com.tomorrow.testnetworkcache-e0beKJuiJ-N2H6sE1CRjSw==/split_lib_slice_3_apk.apk", zip file "/data/app/com.tomorrow.testnetworkcache-e0beKJuiJ-N2H6sE1CRjSw==/split_lib_slice_4_apk.apk", zip file "/data/app/com.tomorrow.testnetworkcache-e0beKJuiJ-N2H6sE1CRjSw==/split_lib_slice_5_apk.apk", zip file "/data/app/com.tomorrow.testnetworkcache-e0beKJuiJ-N2H6sE1CRjSw==/split_lib_slice_6_apk.apk", zip file "/data/app/com.tomorrow.testnetworkcache-e0beKJuiJ-N2H6sE1CRjSw==/split_lib_slice_7_apk.apk", zip file "/data/app/com.tomorrow.testnetworkcache-e0beKJuiJ-N2H6sE1CRjSw==/split_lib_slice_8_apk.apk", zip file "/data/app/com.tomorrow.testnetworkcache-e0beKJuiJ-N2H6sE1CRjSw==/split_lib_slice_9_apk.apk"],nativeLibraryDirectories=[/data/app/com.tomorrow.testnetworkcache-e0beKJuiJ-N2H6sE1CRjSw==/lib/arm64, /system/lib64, /system/vendor/lib64]]]
    2019-09-16 16:31:05.098 HostClass: zwm, classLoader: dalvik.system.DexClassLoader[DexPathList[[zip file "/storage/emulated/0/plugin-debug.apk"],nativeLibraryDirectories=[/system/lib64, /system/vendor/lib64]]]
    2019-09-16 16:31:05.099 HostClass: zwm, pluginClass: class com.tomorrow.plugin.PluginClass
    2019-09-16 16:31:05.099 HostClass: zwm, pluginInstance: com.tomorrow.plugin.PluginClass@957f597
    2019-09-16 16:31:05.099 HostClass: zwm, call pluginMethod: public void com.tomorrow.plugin.PluginClass.method()
    2019-09-16 16:31:05.099 PluginClass: zwm, this is plugin method
    

    从测试情况来看,PathClassLoader跟DexClassLoader功能基本一致。

    相关文章

      网友评论

          本文标题:Android类加载器

          本文链接:https://www.haomeiwen.com/subject/yducuctx.html