Java tutorial
// Copyright 2017 The Bazel Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package com.google.devtools.build.android; import static java.util.stream.Collectors.toSet; import com.android.builder.core.VariantConfiguration; import com.google.common.collect.ImmutableList; import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListeningExecutorService; import com.google.devtools.build.android.ResourceShrinkerAction.Options; import com.google.devtools.build.android.aapt2.Aapt2ConfigOptions; import com.google.devtools.build.android.aapt2.CompiledResources; import com.google.devtools.build.android.aapt2.ResourceCompiler; import com.google.devtools.build.android.aapt2.ResourceLinker; import com.google.devtools.build.android.aapt2.StaticLibrary; import com.google.devtools.common.options.OptionsParser; import com.google.devtools.common.options.ShellQuotedParamsFilePreProcessor; import java.io.Closeable; import java.io.File; import java.nio.file.FileSystems; import java.nio.file.Path; import java.util.concurrent.ExecutionException; import java.util.function.Function; /** * An action to perform resource shrinking using the Gradle resource shrinker. * * <pre> * Example Usage: * java/com/google/build/android/ResourceShrinkerAction * --aapt2 path to sdk/aapt2 * --annotationJar path to sdk/annotationJar * --androidJar path to sdk/androidJar * --shrunkJar path to proguard dead code removal jar * --resources path to processed resources zip * --rTxt path to processed resources R.txt * --primaryManifest path to processed resources AndroidManifest.xml * --dependencyManifest path to dependency library manifest (repeated flag) * --shrunkResourceApk path to write shrunk ap_ * --shrunkResources path to write shrunk resources zip * </pre> */ public class Aapt2ResourceShrinkingAction { public static void main(String[] args) throws Exception { final Profiler profiler = LoggingProfiler.createAndStart("shrink").startTask("flags"); // Parse arguments. OptionsParser optionsParser = OptionsParser.newOptionsParser(Options.class, Aapt2ConfigOptions.class); optionsParser.enableParamsFileSupport(new ShellQuotedParamsFilePreProcessor(FileSystems.getDefault())); optionsParser.parseAndExitUponError(args); Aapt2ConfigOptions aapt2ConfigOptions = optionsParser.getOptions(Aapt2ConfigOptions.class); Options options = optionsParser.getOptions(Options.class); options.dependencyManifests = Converters.concatLists(options.dependencyManifests, options.deprecatedDependencyManifests); profiler.recordEndOf("flags").startTask("setup"); final ListeningExecutorService executorService = ExecutorServiceCloser.createDefaultService(); try (ScopedTemporaryDirectory scopedTmp = new ScopedTemporaryDirectory("android_resources_tmp"); Closeable closer = ExecutorServiceCloser.createWith(executorService)) { Path workingResourcesDirectory = scopedTmp.subDirectoryOf("resources"); final ResourceCompiler resourceCompiler = ResourceCompiler.create(executorService, workingResourcesDirectory, aapt2ConfigOptions.aapt2, aapt2ConfigOptions.buildToolsVersion); profiler.recordEndOf("setup").startTask("compile"); final ResourcesZip resourcesZip = ResourcesZip.createFrom(options.resourcesZip, scopedTmp.subDirectoryOf("merged-resources")); final CompiledResources compiled = resourcesZip .shrink(options.dependencyManifests.stream().map(Path::toFile) .map(manifestToPackageUsing(executorService)).map(futureToString()).collect(toSet()), options.rTxt, options.shrunkJar, options.primaryManifest, options.proguardMapping, options.log, scopedTmp.subDirectoryOf("shrunk-resources")) .writeArchiveTo(options.shrunkResources, false) .compile(resourceCompiler, workingResourcesDirectory); profiler.recordEndOf("compile"); ResourceLinker.create(aapt2ConfigOptions.aapt2, scopedTmp.subDirectoryOf("linking")) .profileUsing(profiler) .dependencies(ImmutableList.of(StaticLibrary.from(aapt2ConfigOptions.androidJar))) .link(compiled).copyPackageTo(options.shrunkApk).copyRTxtTo(options.rTxtOutput); profiler.recordEndOf("shrink"); } } static Function<File, ListenableFuture<String>> manifestToPackageUsing(ListeningExecutorService executor) { return f -> executor.submit(() -> VariantConfiguration.getManifestPackage(f)); } static Function<ListenableFuture<String>, String> futureToString() { return f -> { try { return f.get(); } catch (InterruptedException | ExecutionException e) { throw new RuntimeException(e); } }; } }