jeudi 29 septembre 2016

Get classes from Android in runtime, stop working after gradle upgrade

Introduction


I am working on a Android library to handle SQLite database with ORM (Object Relational Mapping). This library also try to do some automatic functions.

One of this functions, is to automaticly create and drop tables when it is needed, like after a database version upgrade.


Solution


This is my solution, worked for me since long time:


/**
 * Scans all classes accessible from the context class loader which belong to the given package and subpackages.
 *
 * @param packageName The base package
 * @param parentClass The parent class
 * @return The classes that extends from parentClass
 * @throws IOException
 */
public static Class[] getSubClassesOfClass(Class parentClass, String packageName) throws IOException {
    Context context = ApplicationContextProvider.getContext();
    ArrayList<Class> classes = new ArrayList<Class>();
    String packageCodePath = context.getPackageCodePath();
    System.out.println(packageCodePath);
    DexFile df = new DexFile(packageCodePath);
    for (Enumeration<String> iter = df.entries(); iter.hasMoreElements(); ) {
        String className = iter.nextElement();
        System.out.println(className);
        if (className.contains(packageName)) {
            try {
                Class candidateClass = Class.forName(className);
                if (parentClass.isAssignableFrom(candidateClass) && parentClass != candidateClass) {
                    classes.add(candidateClass);
                }
            } catch (NoClassDefFoundError e) {
                //e.printStackTrace();
            } catch (ClassNotFoundException e) {
                //e.printStackTrace();
            } catch (Exception e) {
                //e.printStackTrace();
            } catch (Throwable e) {
                //e.printStackTrace();
            }
        }
    }
    return classes.toArray(new Class[classes.size()]);
}

original solution


Problem


Since i upgrade gradle from 1.3.0 to 2.2.0, this line {DexFile df = new DexFile(packageCodePath);} doesn't work properly anymore. It's retrieving only some classes from a 'com.android.tools...' package. But not longer from my application packages.

In the same answer as solution, there's a comment that says:

This is not working for me since Gradle 2.0.0


Question


¿How i should/could find all classes in my application in runtime since Gradle 2.0.0?





Aucun commentaire:

Enregistrer un commentaire