Skip to content

Commit ece3e1b

Browse files
committed
[tinker] try to fix jit crash on Android N and newer system.
1 parent 6d67fe3 commit ece3e1b

File tree

1 file changed

+15
-5
lines changed

1 file changed

+15
-5
lines changed

tinker-android/tinker-android-loader/src/main/java/com/tencent/tinker/loader/AndroidNClassLoader.java

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@
3939
class 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

Comments
 (0)