diff options
8 files changed, 261 insertions, 46 deletions
diff --git a/anttasks/src/com/android/ant/AaptExecLoopTask.java b/anttasks/src/com/android/ant/AaptExecLoopTask.java index aac61b1..6c98cbd 100644 --- a/anttasks/src/com/android/ant/AaptExecLoopTask.java +++ b/anttasks/src/com/android/ant/AaptExecLoopTask.java @@ -76,6 +76,7 @@ public final class AaptExecLoopTask extends BaseTask { private boolean mForce = true; // true due to legacy reasons private boolean mDebug = false; private boolean mVerbose = false; + private boolean mUseCrunchCache = false; private int mVersionCode = 0; private String mManifest; private ArrayList<Path> mResources; @@ -119,6 +120,14 @@ public final class AaptExecLoopTask extends BaseTask { mVerbose = verbose; } + /** + * Sets the value of the "usecrunchcache" attribute + * @param usecrunch whether to use the crunch cache. + */ + public void setNoCrunch(boolean nocrunch) { + mUseCrunchCache = nocrunch; + } + public void setVersioncode(String versionCode) { if (versionCode.length() > 0) { try { @@ -346,6 +355,11 @@ public final class AaptExecLoopTask extends BaseTask { // aapt command. Only "package" is supported at this time really. task.createArg().setValue(mCommand); + // No crunch flag + if (mUseCrunchCache) { + task.createArg().setValue("--no-crunch"); + } + // force flag if (mForce) { task.createArg().setValue("-f"); diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/AdtConstants.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/AdtConstants.java index d89acb5..1eaa4b9 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/AdtConstants.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/AdtConstants.java @@ -83,6 +83,8 @@ public class AdtConstants { public final static String EXT_DEX = "dex"; //$NON-NLS-1$ /** Extension for temporary resource files, ie "ap_ */ public final static String EXT_RES = "ap_"; //$NON-NLS-1$ + /** Extension for pre-processable images. Right now pngs */ + public final static String EXT_PNG = "png"; //$NON-NLS-1$ private final static String DOT = "."; //$NON-NLS-1$ @@ -149,6 +151,10 @@ public class AdtConstants { /** Absolute path of the resource folder, e.g. "/res".<br> This is a workspace path. */ public final static String WS_RESOURCES = WS_SEP + SdkConstants.FD_RESOURCES; + /** Absolute path of the crunch cache folder, e.g. "/bin/res".<br> This is a workspace path. */ + public final static String WS_CRUNCHCACHE = WS_SEP + SdkConstants.FD_OUTPUT + + WS_SEP + SdkConstants.FD_RESOURCES; + /** Absolute path of the resource folder, e.g. "/assets".<br> This is a workspace path. */ public final static String WS_ASSETS = WS_SEP + SdkConstants.FD_ASSETS; diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/BuildHelper.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/BuildHelper.java index 2ce98e0..1231de3 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/BuildHelper.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/BuildHelper.java @@ -26,17 +26,17 @@ import com.android.ide.eclipse.adt.internal.project.ProjectHelper; import com.android.ide.eclipse.adt.internal.sdk.Sdk; import com.android.prefs.AndroidLocation.AndroidLocationException; import com.android.sdklib.IAndroidTarget; -import com.android.sdklib.SdkConstants; import com.android.sdklib.IAndroidTarget.IOptionalLibrary; +import com.android.sdklib.SdkConstants; import com.android.sdklib.build.ApkBuilder; +import com.android.sdklib.build.ApkBuilder.JarStatus; +import com.android.sdklib.build.ApkBuilder.SigningInfo; import com.android.sdklib.build.ApkCreationException; import com.android.sdklib.build.DuplicateFileException; import com.android.sdklib.build.SealedApkException; -import com.android.sdklib.build.ApkBuilder.JarStatus; -import com.android.sdklib.build.ApkBuilder.SigningInfo; import com.android.sdklib.internal.build.DebugKeyProvider; -import com.android.sdklib.internal.build.SignedJarBuilder; import com.android.sdklib.internal.build.DebugKeyProvider.KeytoolException; +import com.android.sdklib.internal.build.SignedJarBuilder; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IFolder; @@ -96,12 +96,21 @@ public class BuildHelper { private static final String CONSOLE_PREFIX_DX = "Dx"; //$NON-NLS-1$ private final static String TEMP_PREFIX = "android_"; //$NON-NLS-1$ + private static final String COMMAND_CRUNCH = "crunch"; //$NON-NLS-1$ + private static final String COMMAND_PACKAGE = "package"; //$NON-NLS-1$ + private final IProject mProject; private final AndroidPrintStream mOutStream; private final AndroidPrintStream mErrStream; private final boolean mVerbose; private final boolean mDebugMode; + public static final boolean BENCHMARK_FLAG = false; + public static long sStartOverallTime = 0; + public static long sStartJavaCTime = 0; + + private final static int MILLION = 1000000; + /** * An object able to put a marker on a resource. */ @@ -126,6 +135,37 @@ public class BuildHelper { mVerbose = verbose; } + + public void updateCrunchCache() throws AaptExecException, AaptResultException { + // Benchmarking start + long startCrunchTime = 0; + if (BENCHMARK_FLAG) { + String msg = "BENCHMARK ADT: Starting Initial Packaging (.ap_)"; //$NON-NLS-1$ + AdtPlugin.printBuildToConsole(BuildVerbosity.ALWAYS, mProject, msg); + startCrunchTime = System.nanoTime(); + } + + // Get the resources folder to crunch from + IFolder resFolder = mProject.getFolder(AdtConstants.WS_RESOURCES); + List<String> resPaths = new ArrayList<String>(); + resPaths.add(resFolder.getLocation().toOSString()); + + // Get the output folder where the cache is stored. + IFolder cacheFolder = mProject.getFolder(AdtConstants.WS_CRUNCHCACHE); + String cachePath = cacheFolder.getLocation().toOSString(); + + /* For crunching, we don't need the osManifestPath, osAssetsPath, or the configFilter + * parameters for executeAapt + */ + executeAapt(COMMAND_CRUNCH, "", resPaths, "", cachePath, "", 0); + + // Benchmarking end + if (BENCHMARK_FLAG) { + String msg = "BENCHMARK ADT: Ending Initial Package (.ap_). \nTime Elapsed: " //$NON-NLS-1$ + + ((System.nanoTime() - startCrunchTime)/MILLION) + "ms"; //$NON-NLS-1$ + AdtPlugin.printBuildToConsole(BuildVerbosity.ALWAYS, mProject, msg); + } + } /** * Packages the resources of the projet into a .ap_ file. * @param manifestFile the manifest of the project. @@ -142,8 +182,20 @@ public class BuildHelper { public void packageResources(IFile manifestFile, List<IProject> libProjects, String resFilter, int versionCode, String outputFolder, String outputFilename) throws AaptExecException, AaptResultException { + + // Benchmarking start + long startPackageTime = 0; + if (BENCHMARK_FLAG) { + String msg = "BENCHMARK ADT: Starting Initial Packaging (.ap_)"; //$NON-NLS-1$ + AdtPlugin.printBuildToConsole(BuildVerbosity.ALWAYS, mProject, msg); + startPackageTime = System.nanoTime(); + } + // need to figure out some path before we can execute aapt; + // get the cache folder + IFolder cacheFolder = mProject.getFolder(AdtConstants.WS_CRUNCHCACHE); + // get the resource folder IFolder resFolder = mProject.getFolder(AdtConstants.WS_RESOURCES); @@ -155,12 +207,14 @@ public class BuildHelper { assetsFolder = null; } + IPath cacheLocation = cacheFolder.getLocation(); IPath resLocation = resFolder.getLocation(); IPath manifestLocation = manifestFile.getLocation(); if (resLocation != null && manifestLocation != null) { // list of res folder (main project + maybe libraries) ArrayList<String> osResPaths = new ArrayList<String>(); + osResPaths.add(cacheLocation.toOSString()); // PNG crunch cache osResPaths.add(resLocation.toOSString()); //main project // libraries? @@ -181,10 +235,17 @@ public class BuildHelper { } // build the default resource package - executeAapt(osManifestPath, osResPaths, osAssetsPath, + executeAapt(COMMAND_PACKAGE, osManifestPath, osResPaths, osAssetsPath, outputFolder + File.separator + outputFilename, resFilter, versionCode); } + + // Benchmarking end + if (BENCHMARK_FLAG) { + String msg = "BENCHMARK ADT: Ending Initial Package (.ap_). \nTime Elapsed: " //$NON-NLS-1$ + + ((System.nanoTime() - startPackageTime)/MILLION) + "ms"; //$NON-NLS-1$ + AdtPlugin.printBuildToConsole(BuildVerbosity.ALWAYS, mProject, msg); + } } /** @@ -682,10 +743,12 @@ public class BuildHelper { /** * Executes aapt. If any error happen, files or the project will be marked. + * @param command The command for aapt to execute. Currently supported: package and crunch * @param osManifestPath The path to the manifest file * @param osResPath The path to the res folder * @param osAssetsPath The path to the assets folder. This can be null. - * @param osOutFilePath The path to the temporary resource file to create. + * @param osOutFilePath The path to the temporary resource file to create, + * or in the case of crunching the path to the cache to create/update. * @param configFilter The configuration filter for the resources to include * (used with -c option, for example "port,en,fr" to include portrait, English and French * resources.) @@ -694,7 +757,7 @@ public class BuildHelper { * @throws AaptExecException * @throws AaptResultException */ - private void executeAapt(String osManifestPath, + private void executeAapt(String aaptCommand, String osManifestPath, List<String> osResPaths, String osAssetsPath, String osOutFilePath, String configFilter, int versionCode) throws AaptExecException, AaptResultException { IAndroidTarget target = Sdk.getCurrent().getTarget(mProject); @@ -702,50 +765,58 @@ public class BuildHelper { // Create the command line. ArrayList<String> commandArray = new ArrayList<String>(); commandArray.add(target.getPath(IAndroidTarget.AAPT)); - commandArray.add("package"); //$NON-NLS-1$ - commandArray.add("-f");//$NON-NLS-1$ + commandArray.add(aaptCommand); if (AdtPrefs.getPrefs().getBuildVerbosity() == BuildVerbosity.VERBOSE) { commandArray.add("-v"); //$NON-NLS-1$ } - // if more than one res, this means there's a library (or more) and we need - // to activate the auto-add-overlay - if (osResPaths.size() > 1) { - commandArray.add("--auto-add-overlay"); //$NON-NLS-1$ + // Common to all commands + for (String path : osResPaths) { + commandArray.add("-S"); //$NON-NLS-1$ + commandArray.add(path); } - if (mDebugMode) { - commandArray.add("--debug-mode"); //$NON-NLS-1$ - } + if (aaptCommand.equals(COMMAND_PACKAGE)) { + commandArray.add("-f"); //$NON-NLS-1$ + commandArray.add("--no-crunch"); //$NON-NLS-1$ - if (versionCode > 0) { - commandArray.add("--version-code"); //$NON-NLS-1$ - commandArray.add(Integer.toString(versionCode)); - } + // if more than one res, this means there's a library (or more) and we need + // to activate the auto-add-overlay + if (osResPaths.size() > 1) { + commandArray.add("--auto-add-overlay"); //$NON-NLS-1$ + } - if (configFilter != null) { - commandArray.add("-c"); //$NON-NLS-1$ - commandArray.add(configFilter); - } + if (mDebugMode) { + commandArray.add("--debug-mode"); //$NON-NLS-1$ + } - commandArray.add("-M"); //$NON-NLS-1$ - commandArray.add(osManifestPath); + if (versionCode > 0) { + commandArray.add("--version-code"); //$NON-NLS-1$ + commandArray.add(Integer.toString(versionCode)); + } - for (String path : osResPaths) { - commandArray.add("-S"); //$NON-NLS-1$ - commandArray.add(path); - } + if (configFilter != null) { + commandArray.add("-c"); //$NON-NLS-1$ + commandArray.add(configFilter); + } - if (osAssetsPath != null) { - commandArray.add("-A"); //$NON-NLS-1$ - commandArray.add(osAssetsPath); - } + commandArray.add("-M"); //$NON-NLS-1$ + commandArray.add(osManifestPath); + + if (osAssetsPath != null) { + commandArray.add("-A"); //$NON-NLS-1$ + commandArray.add(osAssetsPath); + } - commandArray.add("-I"); //$NON-NLS-1$ - commandArray.add(target.getPath(IAndroidTarget.ANDROID_JAR)); + commandArray.add("-I"); //$NON-NLS-1$ + commandArray.add(target.getPath(IAndroidTarget.ANDROID_JAR)); - commandArray.add("-F"); //$NON-NLS-1$ - commandArray.add(osOutFilePath); + commandArray.add("-F"); //$NON-NLS-1$ + commandArray.add(osOutFilePath); + } else if (aaptCommand.equals(COMMAND_CRUNCH)) { + commandArray.add("-C"); //$NON-NLS-1$ + commandArray.add(osOutFilePath); + } String command[] = commandArray.toArray( new String[commandArray.size()]); @@ -759,6 +830,15 @@ public class BuildHelper { AdtPlugin.printToConsole(mProject, sb.toString()); } + // Benchmarking start + long startAaptTime = 0; + if (BENCHMARK_FLAG) { + String msg = "BENCHMARK ADT: Starting " + aaptCommand //$NON-NLS-1$ + + " call to Aapt"; //$NON-NLS-1$ + AdtPlugin.printBuildToConsole(BuildVerbosity.ALWAYS, mProject, msg); + startAaptTime = System.nanoTime(); + } + // launch int execError = 1; try { @@ -787,6 +867,14 @@ public class BuildHelper { String msg = String.format(Messages.AAPT_Exec_Error, command[0]); throw new AaptExecException(msg, e); } + + // Benchmarking end + if (BENCHMARK_FLAG) { + String msg = "BENCHMARK ADT: Ending " + aaptCommand //$NON-NLS-1$ + + " call to Aapt.\nBENCHMARK ADT: Time Elapsed: " //$NON-NLS-1$ + + ((System.nanoTime() - startAaptTime)/MILLION) + "ms"; //$NON-NLS-1$ + AdtPlugin.printBuildToConsole(BuildVerbosity.ALWAYS, mProject, msg); + } } /** @@ -1090,8 +1178,15 @@ public class BuildHelper { while (true) { String line = outReader.readLine(); if (line != null) { - AdtPlugin.printBuildToConsole(BuildVerbosity.VERBOSE, - project, line); + // If benchmarking always print the lines that + // correspond to benchmarking info returned by ADT + if (BENCHMARK_FLAG && line.startsWith("BENCHMARK:")) { //$NON-NLS-1$ + AdtPlugin.printBuildToConsole(BuildVerbosity.ALWAYS, + project, line); + } else { + AdtPlugin.printBuildToConsole(BuildVerbosity.VERBOSE, + project, line); + } } else { break; } diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/BaseBuilder.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/BaseBuilder.java index 293b340..6b19cc5 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/BaseBuilder.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/BaseBuilder.java @@ -17,8 +17,8 @@ package com.android.ide.eclipse.adt.internal.build.builders; import com.android.ide.common.sdk.LoadStatus; -import com.android.ide.eclipse.adt.AdtPlugin; import com.android.ide.eclipse.adt.AdtConstants; +import com.android.ide.eclipse.adt.AdtPlugin; import com.android.ide.eclipse.adt.internal.build.BuildHelper; import com.android.ide.eclipse.adt.internal.build.Messages; import com.android.ide.eclipse.adt.internal.project.BaseProjectHelper; diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/PostCompilerBuilder.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/PostCompilerBuilder.java index 4b408e6..15aedaf 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/PostCompilerBuilder.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/PostCompilerBuilder.java @@ -69,6 +69,7 @@ public class PostCompilerBuilder extends BaseBuilder { public static final String ID = "com.android.ide.eclipse.adt.ApkBuilder"; //$NON-NLS-1$ private static final String PROPERTY_CONVERT_TO_DEX = "convertToDex"; //$NON-NLS-1$ + private static final String PROPERTY_UPDATE_CRUNCH_CACHE = "updateCrunchCache"; //$NON-NLS-1$ private static final String PROPERTY_PACKAGE_RESOURCES = "packageResources"; //$NON-NLS-1$ private static final String PROPERTY_BUILD_APK = "buildApk"; //$NON-NLS-1$ @@ -85,6 +86,13 @@ public class PostCompilerBuilder extends BaseBuilder { private boolean mConvertToDex = false; /** + * PNG Cache update flag. This is set to true if one of the changed/added/removed + * files is a .png file. Upon visiting all the delta resources, if this + * flag is true, then we know we'll have to update the PNG cache + */ + private boolean mUpdateCrunchCache = false; + + /** * Package resources flag. This is set to true if one of the changed/added/removed * file is a resource file. Upon visiting all the delta resource, if * this flag is true, then we know we'll have to repackage the resources. @@ -226,6 +234,18 @@ public class PostCompilerBuilder extends BaseBuilder { // get a project object IProject project = getProject(); + // Benchmarking start + long startBuildTime = 0; + if (BuildHelper.BENCHMARK_FLAG) { + // End JavaC Timer + String msg = "BENCHMARK ADT: Ending Compilation \n BENCHMARK ADT: Time Elapsed: " + //$NON-NLS-1$ + (System.nanoTime() - BuildHelper.sStartJavaCTime)/Math.pow(10, 6) + "ms"; //$NON-NLS-1$ + AdtPlugin.printBuildToConsole(BuildVerbosity.ALWAYS, project, msg); + msg = "BENCHMARK ADT: Starting PostCompilation"; //$NON-NLS-1$ + AdtPlugin.printBuildToConsole(BuildVerbosity.ALWAYS, project, msg); + startBuildTime = System.nanoTime(); + } + // list of referenced projects. This is a mix of java projects and library projects // and is computed below. IProject[] allRefProjects = null; @@ -274,6 +294,7 @@ public class PostCompilerBuilder extends BaseBuilder { AdtPlugin.printBuildToConsole(BuildVerbosity.VERBOSE, project, Messages.Start_Full_Apk_Build); + mUpdateCrunchCache = true; mPackageResources = true; mConvertToDex = true; mBuildFinalPackage = true; @@ -284,6 +305,7 @@ public class PostCompilerBuilder extends BaseBuilder { // go through the resources and see if something changed. IResourceDelta delta = getDelta(project); if (delta == null) { + mUpdateCrunchCache = true; mPackageResources = true; mConvertToDex = true; mBuildFinalPackage = true; @@ -292,6 +314,7 @@ public class PostCompilerBuilder extends BaseBuilder { delta.accept(dv); // save the state + mUpdateCrunchCache |= dv.getUpdateCrunchCache(); mPackageResources |= dv.getPackageResources(); mConvertToDex |= dv.getConvertToDex(); mBuildFinalPackage |= dv.getMakeFinalPackage(); @@ -339,6 +362,7 @@ public class PostCompilerBuilder extends BaseBuilder { // store the build status in the persistent storage saveProjectBooleanProperty(PROPERTY_CONVERT_TO_DEX , mConvertToDex); + saveProjectBooleanProperty(PROPERTY_UPDATE_CRUNCH_CACHE, mUpdateCrunchCache); saveProjectBooleanProperty(PROPERTY_PACKAGE_RESOURCES, mPackageResources); saveProjectBooleanProperty(PROPERTY_BUILD_APK, mBuildFinalPackage); @@ -474,7 +498,32 @@ public class PostCompilerBuilder extends BaseBuilder { // notified. finalPackage.delete(); - // first we check if we need to package the resources. + // Check if we need to update the PNG cache + if (mUpdateCrunchCache) { + try { + helper.updateCrunchCache(); + } catch (AaptExecException e) { + BaseProjectHelper.markResource(project, AdtConstants.MARKER_PACKAGING, + e.getMessage(), IMarker.SEVERITY_ERROR); + return allRefProjects; + } catch (AaptResultException e) { + // attempt to parse the error output + String[] aaptOutput = e.getOutput(); + boolean parsingError = AaptParser.parseOutput(aaptOutput, project); + // if we couldn't parse the output we display it in the console. + if (parsingError) { + AdtPlugin.printErrorToConsole(project, (Object[]) aaptOutput); + } + } + + // crunch has been done. Reset state + mUpdateCrunchCache = false; + + // and store it + saveProjectBooleanProperty(PROPERTY_UPDATE_CRUNCH_CACHE, mUpdateCrunchCache); + } + + // Check if we need to package the resources. if (mPackageResources) { // remove some aapt_package only markers. removeMarkersFromContainer(project, AdtConstants.MARKER_AAPT_PACKAGE); @@ -653,6 +702,17 @@ public class PostCompilerBuilder extends BaseBuilder { markProject(AdtConstants.MARKER_PACKAGING, msg, IMarker.SEVERITY_ERROR); } + // Benchmarking end + if (BuildHelper.BENCHMARK_FLAG) { + String msg = "BENCHMARK ADT: Ending PostCompilation. \n BENCHMARK ADT: Time Elapsed: " + //$NON-NLS-1$ + ((System.nanoTime() - startBuildTime)/Math.pow(10, 6)) + "ms"; //$NON-NLS-1$ + AdtPlugin.printBuildToConsole(BuildVerbosity.ALWAYS, project, msg); + // End Overall Timer + msg = "BENCHMARK ADT: Done with everything! \n BENCHMARK ADT: Time Elapsed: " + //$NON-NLS-1$ + (System.nanoTime() - BuildHelper.sStartOverallTime)/Math.pow(10, 6) + "ms"; //$NON-NLS-1$ + AdtPlugin.printBuildToConsole(BuildVerbosity.ALWAYS, project, msg); + } + return allRefProjects; } @@ -663,6 +723,7 @@ public class PostCompilerBuilder extends BaseBuilder { // load the build status. We pass true as the default value to // force a recompile in case the property was not found mConvertToDex = loadProjectBooleanProperty(PROPERTY_CONVERT_TO_DEX , true); + mUpdateCrunchCache = loadProjectBooleanProperty(PROPERTY_UPDATE_CRUNCH_CACHE, true); mPackageResources = loadProjectBooleanProperty(PROPERTY_PACKAGE_RESOURCES, true); mBuildFinalPackage = loadProjectBooleanProperty(PROPERTY_BUILD_APK, true); } diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/PostCompilerDeltaVisitor.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/PostCompilerDeltaVisitor.java index 7e426fd..215cbb0 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/PostCompilerDeltaVisitor.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/PostCompilerDeltaVisitor.java @@ -59,6 +59,13 @@ public class PostCompilerDeltaVisitor extends BaseDeltaVisitor /** * compile flag. This is set to true if one of the changed/added/removed + * files is a .png file. Upon visiting all the delta resources, if this + * flag is true, then we know we'll have to run "aapt crunch". + */ + private boolean mUpdateCrunchCache = false; + + /** + * compile flag. This is set to true if one of the changed/added/removed * file is a resource file. Upon visiting all the delta resources, if * this flag is true, then we know we'll have to make the intermediate * apk file. @@ -120,6 +127,10 @@ public class PostCompilerDeltaVisitor extends BaseDeltaVisitor return mConvertToDex; } + public boolean getUpdateCrunchCache() { + return mUpdateCrunchCache; + } + public boolean getPackageResources() { return mPackageResources; } @@ -137,7 +148,7 @@ public class PostCompilerDeltaVisitor extends BaseDeltaVisitor */ public boolean visit(IResourceDelta delta) throws CoreException { // if all flags are true, we can stop going through the resource delta. - if (mConvertToDex && mPackageResources && mMakeFinalPackage) { + if (mConvertToDex && mUpdateCrunchCache && mPackageResources && mMakeFinalPackage) { return false; } @@ -218,6 +229,12 @@ public class PostCompilerDeltaVisitor extends BaseDeltaVisitor // (we don't care about folder being added/removed, only content // is important) if (type == IResource.FILE) { + // Check if this is a .png file. Any modification will + // trigger a cache update + String ext = resource.getFileExtension(); + if (AdtConstants.EXT_PNG.equalsIgnoreCase(ext)) { + mUpdateCrunchCache = true; + } mPackageResources = true; mMakeFinalPackage = true; return false; @@ -225,7 +242,7 @@ public class PostCompilerDeltaVisitor extends BaseDeltaVisitor // for folders, return true only if we don't already know we have to // package the resources. - return mPackageResources == false; + return mPackageResources == false || mUpdateCrunchCache == false; } else if (mAssetPath != null && mAssetPath.isPrefixOf(path)) { // this is the assets folder that was modified. // we don't care what content was changed. All we care diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/ExportHelper.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/ExportHelper.java index 020d1bc..d172a0f 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/ExportHelper.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/ExportHelper.java @@ -124,6 +124,9 @@ public final class ExportHelper { File resourceFile = File.createTempFile(TEMP_PREFIX, AdtConstants.DOT_RES); resourceFile.deleteOnExit(); + // Make sure the PNG crunch cache is up to date + helper.updateCrunchCache(); + // package the resources. helper.packageResources( project.getFile(SdkConstants.FN_ANDROID_MANIFEST_XML), diff --git a/files/ant/main_rules.xml b/files/ant/main_rules.xml index 97e9efb..ff19add 100644 --- a/files/ant/main_rules.xml +++ b/files/ant/main_rules.xml @@ -83,7 +83,9 @@ <property name="out.absolute.dir" location="${out.dir}" /> <property name="out.classes.dir" value="${out.absolute.dir}/classes" /> <property name="out.classes.absolute.dir" location="${out.classes.dir}" /> - + <property name="out.resource.dir" location="${out.dir}/res" /> + <property name="out.resource.absolute.dir" location="${out.resource.dir}" /> + <!-- Intermediate files --> <property name="dex.file.name" value="classes.dex" /> <property name="intermediate.dex.file" @@ -160,6 +162,9 @@ </and> </condition> + <!-- properties for packaging --> + <property name="build.packaging.nocrunch" value="true" /> + <!-- Tools --> <condition property="exe" value=".exe" else=""><os family="windows" /></condition> <property name="adb" location="${android.platform.tools.dir}/adb${exe}" /> @@ -492,12 +497,24 @@ </if> </target> +<!-- Updates the pre-processed PNG cache --> + <target name="-crunch"> + <exec executable="${aapt}"> + <arg value="crunch" /> + <arg value="-v" /> + <arg value="-S" /> + <arg path="${resource.absolute.dir}" /> + <arg value="-C" /> + <arg path="${out.resource.absolute.dir}" /> + </exec> + </target> + <!-- Puts the project's resources into the output package file This actually can create multiple resource package in case Some custom apk with specific configuration have been declared in default.properties. --> - <target name="-package-resources"> + <target name="-package-resources" depends="-crunch"> <echo>Packaging resources</echo> <aapt executable="${aapt}" command="package" @@ -507,8 +524,10 @@ assets="${asset.absolute.dir}" androidjar="${android.jar}" apkfolder="${out.absolute.dir}" + nocrunch="${build.packaging.nocrunch}" resourcefilename="${resource.package.file.name}" resourcefilter="${aapt.resource.filter}"> + <res path="${out.resource.absolute.dir}" /> <res path="${resource.absolute.dir}" /> <!-- <nocompress /> forces no compression on any files in assets or res/raw --> <!-- <nocompress extension="xml" /> forces no compression on specific file extensions in assets and res/raw --> |