本次代码主要想解决DexClassLoader出现ClassNotFound问题,实际上没有解决。但毕竟是自己第一次写的ClassLoader。这里记录一下。
/** * DexClassLoader may cause ClassNotFound because of caching wrong DexInfo in * some cases * * To avoid the caching problem. This class will try to reCreate DexClassLoader * and call loadClass again to solve the issue. * * @author zhenhuachen */ final class RetryDexClassLoader extends DexClassLoader { private String mDexPath; private String mOptimizedDirectory; private String mLibraryPath; private ClassLoader mParent; private DexClassLoader mSecondRecoveryClassLoader; private ArrayList<ClassLoader> mCreatedClassLoaderList = new ArrayList<ClassLoader>(); /** * map of class. */ private final ConcurrentHashMap<String, Class<?>> mClassMap = new ConcurrentHashMap<String, Class<?>>(); public RetryDexClassLoader(String dexPath, String optimizedDirectory, String libraryPath, ClassLoader parent) { super(dexPath, optimizedDirectory, libraryPath, parent); mDexPath = dexPath; mOptimizedDirectory = optimizedDirectory; mLibraryPath = libraryPath; mParent = parent; mCreatedClassLoaderList.add(parent); } private void createRealClassLoader() { MultiParentClassLoader parentLoader = new MultiParentClassLoader(); parentLoader.addParent(mCreatedClassLoaderList); mSecondRecoveryClassLoader = new DexClassLoader(mDexPath, mOptimizedDirectory, mLibraryPath, parentLoader); mCreatedClassLoaderList.add(mSecondRecoveryClassLoader); } @Override public Class<?> loadClass(String name) throws ClassNotFoundException { Class<?> clazz = mClassMap.get(name); if (null != clazz) { return clazz; } try { clazz = mParent.loadClass(name); } catch (ClassNotFoundException e) { try { clazz = findClass(name); } catch (ClassNotFoundException e1) { createRealClassLoader(); clazz = mSecondRecoveryClassLoader.loadClass(name); } } if (null == clazz) { throw new ClassNotFoundException("Didn't find class \"" + name); } else { mClassMap.put(name, clazz); } return clazz; } } final class MultiParentClassLoader extends ClassLoader{ private ArrayList<ClassLoader> mParentLoaderList = new ArrayList<ClassLoader>(); public MultiParentClassLoader() { } @Override public Class<?> loadClass(String className) throws ClassNotFoundException { Class<?> clazz = null; for (ClassLoader loader : mParentLoaderList) { try{ clazz = loader.loadClass(className); } catch(ClassNotFoundException e) { Log.d("MultiParentClassLoader", "loadClass"); } } if (null != clazz) { Log.d("MultiParentClassLoader", "loadClass found in mParentLoaderList"); } return clazz; } public void addParent(ClassLoader loader) { mParentLoaderList.add(loader); } public void addParent(ArrayList<ClassLoader> loaderList) { mParentLoaderList.addAll(loaderList); } }