String apkFileDir = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "test.apk";
String optDir = getDir("optdex", Context.MODE_PRIVATE).getAbsolutePath();
new File(optDir).mkdirs();
//public DexClassLoader (String dexPath, String optimizedDirectory, String libraryPath, ClassLoader parent)
DexClassLoader classLoader = new DexClassLoader(
apkFileDir, //the list of jar/apk files containing classes and resources, delimited by File.pathSeparator, which defaults to ":" on Android
optDir, //directory where optimized dex files should be written; must not be null
null, //the list of directories containing native libraries, delimited by File.pathSeparator; may be null
getClassLoader());
try {
Class<?> testClass = classLoader.loadClass("com.example.dynamicapk.MainActivity");
Method testMethod = testClass.getMethod("testMethod", String.class);
testMethod.setAccessible(true);
String str = (String) testMethod.invoke(testClass.newInstance(), "hello world");
//Toast.makeText(MainActivity.this, str, Toast.LENGTH_LONG).show();
} catch (Exception e) {
e.printStackTrace();
}
DexClassLoader的构造方法中,第一个参数是apk或jar文件的路径(多个文件以:分隔)第二个参数是优化之后的dex文件保存的目录(Android 4.1以上只能是/data/data/包名下的文件夹)第三个参数是用到的.so文件的路径。之后直接用ClassLoader获取Class,然后调用动态加载的类中的方法就可以了。