I am developing a application which automatically load class from external dex from external apk file (external apk file is stored in internal storage of application). The external apk file have class using com.google.gson.
The source code of the application
// Internal storage where the DexClassLoader writes the optimized dex file to.
final File optimizedDexOutputPath = mContext.getDir("optimize_offload", Context.MODE_PRIVATE);
// Initialize the class loader with the s dex file.
DexClassLoader dexClassLoader = new DexClassLoader(apkPath, optimizedDexOutputPath.getAbsolutePath(),
null, mContext.getClassLoader());
// Load the apk class from the class loader.
Class<?> apkProviderClass = dexClassLoader.loadClass(className);
Object obj = apkProviderClass.newInstance();
// call method wrappers
java.lang.reflect.Method method = apkProviderClass.getDeclaredMethod("R_" + methodName, String.class);
System.out.println(method.getName());
method.setAccessible(true);
Object result = method.invoke(obj, params); // Exception here
Class in external apk file has following methods
public long R_catalanSum(String params) {
Gson gson = new Gson();
StartedSumLooperService_catalanSum param =
gson.fromJson(params, StartedSumLooperService_catalanSum.class);
// Call local implementation
return catalanSum(param.n);
}
public long R_fiboSum(String params) {
Gson gson = new Gson();
StartedSumLooperService_fiboSum param =
gson.fromJson(params, StartedSumLooperService_fiboSum.class);
// Call local implementation
return fiboSum(param.n);
}
But I face a following problem while running:
03-05 17:10:59.479: W/dalvikvm(5433): Class resolved by unexpected DEX: Lorg/vkedco/android/startedsumlooperservice/StartedSumLooperService;(0x40f007d8):0x56f3a000 ref [Lcom/google/gson/Gson;] Lcom/google/gson/Gson;(0x40eabac0):0x56daa000
03-05 17:10:59.479: W/dalvikvm(5433): (Lorg/vkedco/android/startedsumlooperservice/StartedSumLooperService; had used a different Lcom/google/gson/Gson; during pre-verification)
According to the Android build process, dex file along with 3rd party library (such as gson here) are bundled into dex files (classes.dex). Hence, I do not need to manual specify all 3rd library when initialize the class loader using DexClassLoader. Am I correct or not?
The answer for this problem is that DEX find 2 versions of gson in class loader and loaded class. The solution is: only use gson in either class loader or loaded class.
There seems to be a solution to the problem on a google forum for this https://groups.google.com/forum/#!topic/android-platform/IP9BuSXgTdQ.
I had the same problem.
But now solved it. We can use the lib in both loader and loading class. I use eclipse.
In loader and loading project added jsoup.jar to libs folder and lib reference
Then we can use the same lib in both class loader and loading.
来源:https://stackoverflow.com/questions/22193668/class-resolved-by-unexpected-dex