Skip to content

Commit

Permalink
[tinker] Bugfix: Avoid fallback to interpret mode when clone DexPathL…
Browse files Browse the repository at this point in the history
…ist.
  • Loading branch information
tys282000 committed May 23, 2017
1 parent 74a2ae0 commit f3e2f5d
Showing 1 changed file with 4 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,8 @@ private AndroidNClassLoader(String dexPath, PathClassLoader parent, Application
}

@SuppressWarnings("unchecked")
private static Object cloneDexPathList(Object originalDexPathList) throws Exception {
private static Object recreateDexPathList(Object originalDexPathList, ClassLoader newDefiningContext) throws Exception {
final Field definingContextField = ShareReflectUtil.findField(originalDexPathList, "definingContext");
final Object definingContext = definingContextField.get(originalDexPathList);
final Field dexElementsField = ShareReflectUtil.findField(originalDexPathList, "dexElements");
final Object[] dexElements = (Object[]) dexElementsField.get(originalDexPathList);
final Field nativeLibraryDirectoriesField = ShareReflectUtil.findField(originalDexPathList, "nativeLibraryDirectories");
Expand Down Expand Up @@ -95,7 +94,7 @@ private static Object cloneDexPathList(Object originalDexPathList) throws Except
final String libraryPath = libraryPathBuilder.toString();

final Constructor<?> dexPathListConstructor = ShareReflectUtil.findConstructor(originalDexPathList, ClassLoader.class, String.class, String.class, File.class);
return dexPathListConstructor.newInstance(definingContext, dexPath, libraryPath, null);
return dexPathListConstructor.newInstance(newDefiningContext, dexPath, libraryPath, null);
}

private static AndroidNClassLoader createAndroidNClassLoader(PathClassLoader originalClassLoader, Application application) throws Exception {
Expand All @@ -108,13 +107,9 @@ private static AndroidNClassLoader createAndroidNClassLoader(PathClassLoader ori
// dexPathList in original classloader so that after the newly loaded base dex was bound to
// AndroidNClassLoader we can still load class in base dex from original classloader.

Object newPathList = cloneDexPathList(originPathList);
Object newPathList = recreateDexPathList(originPathList, androidNClassLoader);

//should reflect definingContext also
final Field definingContextField = ShareReflectUtil.findField(newPathList, "definingContext");
definingContextField.set(newPathList, androidNClassLoader);

//just use PathClassloader's pathList
// Update new classloader's pathList.
pathListField.set(androidNClassLoader, newPathList);

return androidNClassLoader;
Expand Down

0 comments on commit f3e2f5d

Please sign in to comment.