Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Find all classes in a package in Android

Tags:

java

android

How can i find all classes inside a package on Android? I use PathClassLoader, but it always returns an empty enumeration?

Additional info

Tried the suggested Reflections approach. Couple of important points about reflections library. The library available through maven central is not compatible with Android and gives dex errors. I had to include source and compile dom4j, java-assist.

The problem with reflections, and my original solution is that PathClassLoader in android returns an empty enumeration for package.

The issue with approach is that getResource in Android is always returning empty enumeration.

final String resourceName = aClass.getName().replace(".", "/") + ".class";

for (ClassLoader classLoader : loaders) {
      try {
            final URL url = classLoader.getResource(resourceName);
            if (url != null) {
                final String normalizedUrl = url.toExternalForm().substring(0, url.toExternalForm().lastIndexOf(aClass.getPackage().getName().replace(".", "/")));
                return new URL(normalizedUrl);
            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }
   }
like image 455
user210504 Avatar asked Mar 16 '13 05:03

user210504


2 Answers

Using DexFile to list all classes in your apk:

    try {
        DexFile df = new DexFile(context.getPackageCodePath());
        for (Enumeration<String> iter = df.entries(); iter.hasMoreElements();) {
            String s = iter.nextElement();
        }
    } catch (IOException e) {
        e.printStackTrace();
    }

the rest is using regexp or something else to filter out your desired class.

like image 130
tao Avatar answered Sep 24 '22 01:09

tao


Actually i found solution. Thanks for tao reply.

private String[] getClassesOfPackage(String packageName) {
    ArrayList<String> classes = new ArrayList<String>();
    try {
        String packageCodePath = getPackageCodePath();
        DexFile df = new DexFile(packageCodePath);
        for (Enumeration<String> iter = df.entries(); iter.hasMoreElements(); ) {
            String className = iter.nextElement();
            if (className.contains(packageName)) {
                classes.add(className.substring(className.lastIndexOf(".") + 1, className.length()));
            }
        }
    } catch (IOException e) {
        e.printStackTrace();
    }

    return classes.toArray(new String[classes.size()]);
}

Tested on Android 5.0 Lolipop

like image 35
Sergey Shustikov Avatar answered Sep 22 '22 01:09

Sergey Shustikov