// Not safe to execute multiple times. @Override public Collection<File> execute() throws IOException { ClasspathTraverser classpathTraverser = new DefaultClasspathTraverser(); // Compute the total size of the inputs so that we can figure out whether its safe // to begin putting non-essential entries into the primary zip. // TODO(devjasta): There's a more compact way of doing this by writing the primary zip during // this first-pass step then assigning it as the "currentSecondaryOut" to complete the second // pass. We're already tracking unique entries so we would not end up adding those primary // entries twice. classpathTraverser.traverse( new ClasspathTraversal(inFiles) { @Override public void visit(FileLike entry) { long entrySize = entry.getSize(); if (entrySize > 0) { remainingSize += entrySize; } } }); primaryOut = newZipOutput(outPrimary); secondaryDexWriter.reset(); try { for (File inFile : inFiles) { classpathTraverser.traverse( new ClasspathTraversal(ImmutableSet.of(inFile)) { @Override public void visit(FileLike entry) throws IOException { processEntry(entry); } }); // The soft limit was tripped (and not the hard limit). Flag that the next non-zero length // entry should create a new zip. DefaultZipOutputStreamHelper currentSecondaryOut = secondaryDexWriter.getCurrentOutput(); if (currentSecondaryOut != null && currentSecondaryOut.getCurrentSize() >= zipSizeSoftLimit) { secondaryDexWriter.finishCurrentZipFile(); } } } finally { primaryOut.close(); secondaryDexWriter.close(); } return secondaryDexWriter.getFiles(); }