一、概念

//测试代码
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
网友评论