use of com.android.sdklib.BuildToolInfo in project atlas by alibaba.
the class AtlasBuilder method processResources.
/**
* 对主bundle的资源进行处理
*
* @param aaptCommand
* @param enforceUniquePackageName
* @param processOutputHandler
* @throws IOException
* @throws InterruptedException
* @throws ProcessException
*/
public void processResources(AaptPackageProcessBuilder aaptCommand, boolean enforceUniquePackageName, ProcessOutputHandler processOutputHandler) throws IOException, InterruptedException, ProcessException {
checkState(getTargetInfo() != null, "Cannot call processResources() before setTargetInfo() is called.");
BuildToolInfo buildToolInfo = getTargetInfo().getBuildTools();
// launch aapt: create the command line
ProcessInfo processInfo = aaptCommand.build(buildToolInfo, getTargetInfo().getTarget(), getLogger());
processInfo = new TProcessInfo(processInfo);
// 打印日志
// if (null != getLogger()) {
// getLogger().info("[Aapt]" + processInfo.getExecutable() + " "
// + StringUtils.join(processInfo.getArgs(), " "));
// }
ProcessResult result = getProcessExecutor().execute(processInfo, processOutputHandler);
result.rethrowFailure().assertNormalExitValue();
// If the project has libraries, R needs to be created for each library.
if (aaptCommand.getSourceOutputDir() != null && !aaptCommand.getLibraries().isEmpty()) {
SymbolLoader fullSymbolValues = null;
// First pass processing the libraries, collecting them by packageName,
// and ignoring the ones that have the same package name as the application
// (since that R class was already created).
String appPackageName = aaptCommand.getPackageForR();
if (appPackageName == null) {
appPackageName = ManifestFileUtils.getPackage(aaptCommand.getManifestFile());
}
// list of all the symbol loaders per package names.
Multimap<String, SymbolLoader> libMap = ArrayListMultimap.create();
for (AndroidLibrary lib : aaptCommand.getLibraries()) {
if (lib.isOptional()) {
continue;
}
String packageName = ManifestFileUtils.getPackage(lib.getManifest());
if (appPackageName == null) {
continue;
}
if (appPackageName.equals(packageName)) {
if (enforceUniquePackageName) {
String msg = String.format("Error: A library uses the same package as this project: %s", packageName);
throw new RuntimeException(msg);
}
// ignore libraries that have the same package name as the app
continue;
}
File rFile = lib.getSymbolFile();
// if the library has no resource, this file won't exist.
if (rFile.isFile()) {
// resources anywhere.
if (fullSymbolValues == null) {
fullSymbolValues = new SymbolLoader(new File(aaptCommand.getSymbolOutputDir(), "R.txt"), getLogger());
fullSymbolValues.load();
}
SymbolLoader libSymbols = new SymbolLoader(rFile, getLogger());
libSymbols.load();
// store these symbols by associating them with the package name.
libMap.put(packageName, libSymbols);
}
}
// now loop on all the package name, merge all the symbols to write, and write them
for (String packageName : libMap.keySet()) {
Collection<SymbolLoader> symbols = libMap.get(packageName);
if (enforceUniquePackageName && symbols.size() > 1) {
String msg = String.format("Error: more than one library with package name '%s'", packageName);
throw new RuntimeException(msg);
}
SymbolWriter writer = new SymbolWriter(aaptCommand.getSourceOutputDir(), packageName, fullSymbolValues, false);
for (SymbolLoader symbolLoader : symbols) {
writer.addSymbolsToWrite(symbolLoader);
}
writer.write();
}
}
}
use of com.android.sdklib.BuildToolInfo in project atlas by alibaba.
the class AtlasBuilder method processResources.
@Override
public void processResources(Aapt aapt, Builder aaptConfigBuilder, boolean enforceUniquePackageName) throws IOException, InterruptedException, ProcessException {
if (aapt instanceof AaptV1) {
try {
getTargetInfo();
AaptOptions aaptOptions = (AaptOptions) FieldUtils.readField(aaptConfigBuilder.build(), "mAaptOptions", true);
ProcessExecutor processExecutor = (ProcessExecutor) FieldUtils.readField(aapt, "mProcessExecutor", true);
ProcessOutputHandler processOutputHandler = (ProcessOutputHandler) FieldUtils.readField(aapt, "mProcessOutputHandler", true);
BuildToolInfo buildToolInfo = (BuildToolInfo) FieldUtils.readField(aapt, "mBuildToolInfo", true);
PngProcessMode processMode = (PngProcessMode) FieldUtils.readField(aapt, "mProcessMode", true);
int cruncherProcesses = aaptOptions.getCruncherProcesses();
aapt = new AtlasAapt(processExecutor, processOutputHandler, buildToolInfo, getLogger(), processMode, cruncherProcesses);
} catch (Throwable e) {
throw new GradleException("aapt exception", e);
}
}
super.processResources(aapt, aaptConfigBuilder, enforceUniquePackageName);
}
use of com.android.sdklib.BuildToolInfo in project atlas by alibaba.
the class AtlasBuilder method getTargetInfo.
@Override
public TargetInfo getTargetInfo() {
if (!updateAapt && useCustomAapt) {
BuildToolInfo defaultBuildToolInfo = super.getTargetInfo().getBuildTools();
File customAaptFile = getAapt();
try {
Method method = defaultBuildToolInfo.getClass().getDeclaredMethod("add", PathId.class, File.class);
method.setAccessible(true);
method.invoke(defaultBuildToolInfo, PathId.AAPT, customAaptFile);
} catch (Throwable e) {
throw new GradleException(e.getMessage());
}
updateAapt = true;
}
return super.getTargetInfo();
}
use of com.android.sdklib.BuildToolInfo in project android by JetBrains.
the class ConfigureAndroidProjectPath method putSdkDependentParams.
/**
* Populate the given state with a set of variables that depend on the user's installed SDK. This method should
* be called early in the initialization of a wizard or path.
* Variables:
* Build Tools Version: Used to populate the project level build.gradle with the correct Gradle plugin version number
* If the required build tools version is not installed, a request is added for installation
* SDK Home: The location of the installed SDK
*
* @param state the state store to populate with the values stored in the SDK
*/
public static void putSdkDependentParams(@NotNull ScopedStateStore state) {
final AndroidSdkHandler sdkHandler = AndroidSdks.getInstance().tryToChooseSdkHandler();
StudioLoggerProgressIndicator progress = new StudioLoggerProgressIndicator(ConfigureAndroidProjectPath.class);
BuildToolInfo buildTool = sdkHandler.getLatestBuildTool(progress, false);
Revision minimumRequiredBuildToolVersion = Revision.parseRevision(SdkConstants.MIN_BUILD_TOOLS_VERSION);
if (buildTool != null && buildTool.getRevision().compareTo(minimumRequiredBuildToolVersion) >= 0) {
state.put(WizardConstants.BUILD_TOOLS_VERSION_KEY, buildTool.getRevision().toString());
} else {
// We need to install a new build tools version
state.listPush(WizardConstants.INSTALL_REQUESTS_KEY, DetailsTypes.getBuildToolsPath(minimumRequiredBuildToolVersion));
state.put(WizardConstants.BUILD_TOOLS_VERSION_KEY, minimumRequiredBuildToolVersion.toString());
}
File location = sdkHandler.getLocation();
if (location != null) {
// Gradle expects a platform-neutral path
state.put(WizardConstants.SDK_DIR_KEY, FileUtil.toSystemIndependentName(location.getPath()));
}
}
use of com.android.sdklib.BuildToolInfo in project android by JetBrains.
the class AndroidApt method packageResources.
public static Map<AndroidCompilerMessageKind, List<String>> packageResources(@NotNull IAndroidTarget target, int platformToolsRevision, @NotNull String manifestPath, @NotNull String[] resPaths, @NotNull String[] osAssetDirPaths, @NotNull String outputPath, @Nullable String configFilter, boolean debugMode, int versionCode, @Nullable String customManifestPackage, @Nullable String additionalParameters, FileFilter assetsFilter) throws IOException {
for (String resDirPath : resPaths) {
if (FileUtil.isAncestor(resDirPath, outputPath, false)) {
throw new IOException("Resource directory " + FileUtil.toSystemDependentName(resDirPath) + " contains output " + FileUtil.toSystemDependentName(outputPath));
}
}
for (String assetsDirPath : osAssetDirPaths) {
if (FileUtil.isAncestor(assetsDirPath, outputPath, false)) {
throw new IOException("Assets directory " + FileUtil.toSystemDependentName(assetsDirPath) + " contains output " + FileUtil.toSystemDependentName(outputPath));
}
}
BuildToolInfo buildToolInfo = target.getBuildToolInfo();
if (buildToolInfo == null) {
return Collections.singletonMap(AndroidCompilerMessageKind.ERROR, Collections.singletonList("No Build Tools in the Android SDK."));
}
final ArrayList<String> args = new ArrayList<String>();
args.add(buildToolInfo.getPath(BuildToolInfo.PathId.AAPT));
args.add(COMMAND_PACKAGE);
for (String path : resPaths) {
args.add("-S");
args.add(path);
}
args.add("-f");
if (platformToolsRevision < 0 || platformToolsRevision > 7) {
args.add("--no-crunch");
}
if (resPaths.length > 1) {
args.add("--auto-add-overlay");
}
if (debugMode) {
args.add("--debug-mode");
}
if (versionCode > 0) {
args.add("--version-code");
args.add(Integer.toString(versionCode));
}
if (configFilter != null) {
args.add("-c");
args.add(configFilter);
}
args.add("-M");
args.add(manifestPath);
File tempDir = null;
try {
if (osAssetDirPaths.length > 0) {
final String[] nonEmptyAssetDirs = getNonEmptyExistingDirs(osAssetDirPaths);
if (nonEmptyAssetDirs.length > 0) {
if (nonEmptyAssetDirs.length == 1) {
args.add("-A");
args.add(nonEmptyAssetDirs[0]);
} else {
tempDir = FileUtil.createTempDirectory("android_combined_assets", "tmp");
for (int i = nonEmptyAssetDirs.length - 1; i >= 0; i--) {
final String assetDir = nonEmptyAssetDirs[i];
FileUtil.copyDir(new File(assetDir), tempDir, assetsFilter);
}
args.add("-A");
args.add(tempDir.getPath());
}
}
}
args.add("-I");
args.add(target.getPath(IAndroidTarget.ANDROID_JAR));
if (customManifestPackage != null) {
args.add("--rename-manifest-package");
args.add(customManifestPackage);
}
if (additionalParameters != null && additionalParameters.length() > 0) {
args.addAll(ParametersListUtil.parse(additionalParameters));
}
args.add("-F");
args.add(outputPath);
LOG.info(AndroidCommonUtils.command2string(args));
return AndroidExecutionUtil.doExecute(ArrayUtil.toStringArray(args));
} finally {
if (tempDir != null) {
FileUtil.delete(tempDir);
}
}
}
Aggregations