3939class AndroidNClassLoader extends PathClassLoader {
4040 private static final String TAG = "Tinker.NClassLoader" ;
4141
42+ private static Object oldDexPathListHolder = null ;
43+
4244 private final PathClassLoader originClassLoader ;
4345 private String applicationClassName ;
4446
@@ -52,7 +54,11 @@ private AndroidNClassLoader(String dexPath, PathClassLoader parent, Application
5254 }
5355
5456 @ SuppressWarnings ("unchecked" )
55- private static Object recreateDexPathList (Object originalDexPathList , ClassLoader newDefiningContext ) throws Exception {
57+ private static Object recreateDexPathList (Object originalDexPathList , ClassLoader newDefiningContext , boolean createEmptyOne ) throws Exception {
58+ final Constructor <?> dexPathListConstructor = ShareReflectUtil .findConstructor (originalDexPathList , ClassLoader .class , String .class , String .class , File .class );
59+ if (createEmptyOne ) {
60+ return dexPathListConstructor .newInstance (newDefiningContext , "" , null , null );
61+ }
5662 final Field dexElementsField = ShareReflectUtil .findField (originalDexPathList , "dexElements" );
5763 final Object [] dexElements = (Object []) dexElementsField .get (originalDexPathList );
5864 final Field nativeLibraryDirectoriesField = ShareReflectUtil .findField (originalDexPathList , "nativeLibraryDirectories" );
@@ -92,8 +98,6 @@ private static Object recreateDexPathList(Object originalDexPathList, ClassLoade
9298 }
9399
94100 final String libraryPath = libraryPathBuilder .toString ();
95-
96- final Constructor <?> dexPathListConstructor = ShareReflectUtil .findConstructor (originalDexPathList , ClassLoader .class , String .class , String .class , File .class );
97101 return dexPathListConstructor .newInstance (newDefiningContext , dexPath , libraryPath , null );
98102 }
99103
@@ -106,12 +110,18 @@ private static AndroidNClassLoader createAndroidNClassLoader(PathClassLoader ori
106110 // To avoid 'dex file register with multiple classloader' exception on Android O, we must keep old
107111 // dexPathList in original classloader so that after the newly loaded base dex was bound to
108112 // AndroidNClassLoader we can still load class in base dex from original classloader.
109-
110- Object newPathList = recreateDexPathList (originPathList , androidNClassLoader );
113+ Object newPathList = recreateDexPathList (originPathList , androidNClassLoader , false );
111114
112115 // Update new classloader's pathList.
113116 pathListField .set (androidNClassLoader , newPathList );
114117
118+ // Recreate old dexPathList.
119+ oldDexPathListHolder = originPathList ;
120+ Object emptyOldPathList = recreateDexPathList (originPathList , originalClassLoader , true );
121+ pathListField .set (originalClassLoader , emptyOldPathList );
122+ Object recreatedOldPathList = recreateDexPathList (originPathList , originalClassLoader , false );
123+ pathListField .set (originalClassLoader , recreatedOldPathList );
124+
115125 return androidNClassLoader ;
116126 }
117127
0 commit comments