4

I put a .jar file containing .dex file to directory "/sdcard", then I try to load the class in the .jar file using DexClassLoader and PathClassLoader respectively. Both of them can load the class successfully. What are differences between them? Here is my code:

String dexPath = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "test.jar";
PathClassLoader classLoader1 = new PathClassLoader(dexPath, getClassLoader());
DexClassLoader classLoader2 = new DexClassLoader(dexPath, getDir("dex", 0).getAbsolutePath(), null, getClassLoader());
try {
     Class clazz1 = classLoader1.loadClass("com.focans.loader.Peter");
     Class clazz2 = classLoader2.loadClass("com.focans.loader.Peter");
} catch (Exception e) {
     e.printStackTrace();
}
dreamer
  • 153
  • 2
  • 10

2 Answers2

3

You should read official Guideline about

DexClassLoader

A class loader that loads classes from .jar and .apk files containing a classes.dex entry. This can be used to execute code not installed as part of an application.

PathClassLoader

Provides a simple ClassLoader implementation that operates on a list of files and directories in the local file system, but does not attempt to load classes from the network. Android uses this class for its system class loader and for its application class loader(s).

DexClassLoader is instantiated to load the library from the extracted secondary dex file.

PathClassLoader Used to load classes within ant with a different classpath from that used to start ant. Note that it is possible to force a class into this loader even when that class is on the system classpath by using the forceLoadClass method. Any subsequent classes loaded by that class will then use this loader rather than the system class loader.

IntelliJ Amiya
  • 74,896
  • 15
  • 165
  • 198
  • 2
    What do you mean by `ant`? Also there does not seem to be any `forceLoadClass` method in PathClassLoader. – Codebender Mar 30 '17 at 03:19
3

For Android 8.1 (API 27) and up, DexClassLoader and PathClassLoader are essentially identical. They both extend BaseDexClassLoader, and immediately call super() when constructed. There are no implementation differences or side effects (at least in the AOSP versions I've referenced here).

In prior versions (8.0 and earlier) DexClassLoader accepted an argument for String optimizedDirectory, which allowed the caller to specify the directory to store optimized Dex code (ODEX files), for the Dex that was loaded by the class loader. This argument still exists in newer versions of Android, but it has no effect.

BLuFeNiX
  • 2,496
  • 2
  • 20
  • 40
  • According to [Android doc](https://developer.android.com/reference/dalvik/system/DexClassLoader.html#DexClassLoader(java.lang.String,%20java.lang.String,%20java.lang.String,%20java.lang.ClassLoader)), param optimizedDirectory of DexClassLoader is deprecated and has no effect since API level 26. – Better Shao Sep 23 '20 at 05:58
  • Seems the Android doc is somewhat misleading, according to code, param optimizedDirectory is deprecated since API level 27 instead of 26. [8.0 code](http://androidxref.com/8.0.0_r4/xref/libcore/dalvik/src/main/java/dalvik/system/DexClassLoader.java) v.s. [8.1 code](http://androidxref.com/8.1.0_r33/xref/libcore/dalvik/src/main/java/dalvik/system/DexClassLoader.java) – Better Shao Sep 23 '20 at 06:30