Пример #1
0
  @VisibleForTesting
  static void writeAar(
      Path aar, final MergedAndroidData data, Path manifest, Path rtxt, Path classes)
      throws IOException {
    try (final ZipOutputStream zipOut = new ZipOutputStream(new FileOutputStream(aar.toFile()))) {
      ZipEntry manifestEntry = new ZipEntry("AndroidManifest.xml");
      zipOut.putNextEntry(manifestEntry);
      zipOut.write(Files.readAllBytes(manifest));
      zipOut.closeEntry();

      ZipEntry classJar = new ZipEntry("classes.jar");
      zipOut.putNextEntry(classJar);
      zipOut.write(Files.readAllBytes(classes));
      zipOut.closeEntry();

      Files.walkFileTree(
          data.getResourceDirFile().toPath(),
          new ZipDirectoryWriter(zipOut, data.getResourceDirFile().toPath(), "res"));

      ZipEntry r = new ZipEntry("R.txt");
      zipOut.putNextEntry(r);
      zipOut.write(Files.readAllBytes(rtxt));
      zipOut.closeEntry();

      if (data.getAssetDirFile().exists() && data.getAssetDirFile().list().length > 0) {
        Files.walkFileTree(
            data.getAssetDirFile().toPath(),
            new ZipDirectoryWriter(zipOut, data.getAssetDirFile().toPath(), "assets"));
      }
    }
    aar.toFile().setLastModified(EPOCH);
  }
  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)));
  }