美文网首页
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