public static void main(String[] args) throws Exception { final Stopwatch timer = Stopwatch.createStarted(); OptionsParser optionsParser = OptionsParser.newOptionsParser(Options.class, AaptConfigOptions.class); optionsParser.parseAndExitUponError(args); aaptConfigOptions = optionsParser.getOptions(AaptConfigOptions.class); options = optionsParser.getOptions(Options.class); FileSystem fileSystem = FileSystems.getDefault(); Path working = fileSystem.getPath("").toAbsolutePath(); final AndroidResourceProcessor resourceProcessor = new AndroidResourceProcessor(STD_LOGGER); try { final Path tmp = Files.createTempDirectory("android_resources_tmp"); // Clean up the tmp file on exit to keep diskspace low. tmp.toFile().deleteOnExit(); final Path expandedOut = tmp.resolve("tmp-expanded"); final Path deduplicatedOut = tmp.resolve("tmp-deduplicated"); final Path mergedAssets = tmp.resolve("merged_assets"); final Path mergedResources = tmp.resolve("merged_resources"); final Path filteredResources = tmp.resolve("resources-filtered"); final Path densityManifest = tmp.resolve("manifest-filtered/AndroidManifest.xml"); final Path processedManifest = tmp.resolve("manifest-processed/AndroidManifest.xml"); Path generatedSources = null; if (options.srcJarOutput != null || options.rOutput != null || options.symbolsTxtOut != null) { generatedSources = tmp.resolve("generated_resources"); } LOGGER.fine(String.format("Setup finished at %sms", timer.elapsed(TimeUnit.MILLISECONDS))); final ImmutableList<DirectoryModifier> modifiers = ImmutableList.of( new PackedResourceTarExpander(expandedOut, working), new FileDeDuplicator(Hashing.murmur3_128(), deduplicatedOut, working)); // Resources can appear in both the direct dependencies and transitive -- use a set to // ensure depeduplication. List<DependencyAndroidData> data = ImmutableSet.<DependencyAndroidData>builder() .addAll(options.directData) .addAll(options.transitiveData) .build() .asList(); final MergedAndroidData mergedData = resourceProcessor.mergeData( options.primaryData, data, mergedResources, mergedAssets, modifiers, selectPngCruncher(), true); LOGGER.fine(String.format("Merging finished at %sms", timer.elapsed(TimeUnit.MILLISECONDS))); final DensityFilteredAndroidData filteredData = mergedData.filter( new DensitySpecificResourceFilter( options.densities, filteredResources, mergedResources), new DensitySpecificManifestProcessor(options.densities, densityManifest)); LOGGER.fine( String.format( "Density filtering finished at %sms", timer.elapsed(TimeUnit.MILLISECONDS))); final MergedAndroidData processedManifestData = resourceProcessor.processManifest( options.packageType, options.packageForR, options.applicationId, options.versionCode, options.versionName, filteredData, processedManifest); resourceProcessor.processResources( aaptConfigOptions.aapt, aaptConfigOptions.androidJar, aaptConfigOptions.buildToolsVersion, options.packageType, aaptConfigOptions.debug, options.packageForR, new FlagAaptOptions(aaptConfigOptions), aaptConfigOptions.resourceConfigs, aaptConfigOptions.splits, processedManifestData, data, generatedSources, options.packagePath, options.proguardOutput, options.mainDexProguardOutput, options.resourcesOutput != null ? processedManifestData.getResourceDir().resolve("values").resolve("public.xml") : null); LOGGER.fine(String.format("aapt finished at %sms", timer.elapsed(TimeUnit.MILLISECONDS))); if (options.manifestOutput != null) { resourceProcessor.copyManifestToOutput(processedManifestData, options.manifestOutput); } if (options.srcJarOutput != null) { resourceProcessor.createSrcJar( generatedSources, options.srcJarOutput, VariantConfiguration.Type.LIBRARY == options.packageType); } if (options.rOutput != null) { resourceProcessor.copyRToOutput( generatedSources, options.rOutput, VariantConfiguration.Type.LIBRARY == options.packageType); } if (options.symbolsTxtOut != null) { resourceProcessor.copyRToOutput( generatedSources, options.symbolsTxtOut, VariantConfiguration.Type.LIBRARY == options.packageType); } if (options.resourcesOutput != null) { resourceProcessor.createResourcesZip( processedManifestData.getResourceDir(), processedManifestData.getAssetDir(), options.resourcesOutput); } LOGGER.fine( String.format("Packaging finished at %sms", timer.elapsed(TimeUnit.MILLISECONDS))); } catch (MergingException e) { LOGGER.log(java.util.logging.Level.SEVERE, "Error during merging resources", e); throw e; } catch (IOException | InterruptedException | LoggedErrorException e) { LOGGER.log(java.util.logging.Level.SEVERE, "Error during processing resources", e); throw e; } catch (Exception e) { LOGGER.log(java.util.logging.Level.SEVERE, "Unexpected", e); throw e; } finally { resourceProcessor.shutdown(); } LOGGER.fine(String.format("Resources processed in %sms", timer.elapsed(TimeUnit.MILLISECONDS))); }