FileDocCategorySizeDatePackage
MainDexListBuilder.javaAPI DocAndroid 5.1 API6492Thu Mar 12 22:18:30 GMT 2015com.android.multidex

MainDexListBuilder

public class MainDexListBuilder extends Object
This is a command line tool used by mainDexClasses script to build a main dex classes list. First argument of the command line is an archive, each class file contained in this archive is used to identify a class that can be used during secondary dex installation, those class files are not opened by this tool only their names matter. Other arguments must be zip files or directories, they constitute in a classpath in with the classes named by the first argument will be searched. Each searched class must be found. On each of this classes are searched for their dependencies to other classes. The tool also browses for classes annotated by runtime visible annotations and adds them to the list/ Finally the tools prints on standard output a list of class files names suitable as content of the file argument --main-dex-list of dx.

Fields Summary
private static final String
CLASS_EXTENSION
private static final int
STATUS_ERROR
private static final String
EOL
private static String
USAGE_MESSAGE
private Set
filesToKeep
Constructors Summary
public MainDexListBuilder(String rootJar, String pathString)

        ZipFile jarOfRoots = null;
        Path path = null;
        try {
            try {
                jarOfRoots = new ZipFile(rootJar);
            } catch (IOException e) {
                throw new IOException("\"" + rootJar + "\" can not be read as a zip archive. ("
                        + e.getMessage() + ")", e);
            }
            path = new Path(pathString);

            ClassReferenceListBuilder mainListBuilder = new ClassReferenceListBuilder(path);
            mainListBuilder.addRoots(jarOfRoots);
            for (String className : mainListBuilder.getClassNames()) {
                filesToKeep.add(className + CLASS_EXTENSION);
            }
            keepAnnotated(path);
        } finally {
            try {
                jarOfRoots.close();
            } catch (IOException e) {
                // ignore
            }
            if (path != null) {
                for (ClassPathElement element : path.elements) {
                    try {
                        element.close();
                    } catch (IOException e) {
                        // keep going, lets do our best.
                    }
                }
            }
        }
    
Methods Summary
public java.util.SetgetMainDexList()
Returns a list of classes to keep. This can be passed to dx as a file with --main-dex-list.

        return filesToKeep;
    
private booleanhasRuntimeVisibleAnnotation(com.android.dx.cf.iface.HasAttribute element)

        Attribute att = element.getAttributes().findFirst(
                AttRuntimeVisibleAnnotations.ATTRIBUTE_NAME);
        return (att != null && ((AttRuntimeVisibleAnnotations)att).getAnnotations().size()>0);
    
private voidkeepAnnotated(Path path)
Keep classes annotated with runtime annotations.

        for (ClassPathElement element : path.getElements()) {
            forClazz:
                for (String name : element.list()) {
                    if (name.endsWith(CLASS_EXTENSION)) {
                        DirectClassFile clazz = path.getClass(name);
                        if (hasRuntimeVisibleAnnotation(clazz)) {
                            filesToKeep.add(name);
                        } else {
                            MethodList methods = clazz.getMethods();
                            for (int i = 0; i<methods.size(); i++) {
                                if (hasRuntimeVisibleAnnotation(methods.get(i))) {
                                    filesToKeep.add(name);
                                    continue forClazz;
                                }
                            }
                            FieldList fields = clazz.getFields();
                            for (int i = 0; i<fields.size(); i++) {
                                if (hasRuntimeVisibleAnnotation(fields.get(i))) {
                                    filesToKeep.add(name);
                                    continue forClazz;
                                }
                            }
                        }
                    }
                }
        }
    
public static voidmain(java.lang.String[] args)


         

        if (args.length != 2) {
            printUsage();
            System.exit(STATUS_ERROR);
        }

        try {

            MainDexListBuilder builder = new MainDexListBuilder(args[0], args[1]);
            Set<String> toKeep = builder.getMainDexList();
            printList(toKeep);
        } catch (IOException e) {
            System.err.println("A fatal error occured: " + e.getMessage());
            System.exit(STATUS_ERROR);
            return;
        }
    
private static voidprintList(java.util.Set fileNames)

        for (String fileName : fileNames) {
            System.out.println(fileName);
        }
    
private static voidprintUsage()

        System.err.print(USAGE_MESSAGE);