From 5705687f1ebdcc4b4dcd89aec059fb4c8d04b7cf Mon Sep 17 00:00:00 2001 From: Eugene Kudelevsky Date: Mon, 4 Jun 2012 19:57:23 +0400 Subject: [PATCH] android artifacts: align apk --- .../messages/AndroidBundle.properties | 3 +- .../AndroidApplicationArtifactProperties.java | 38 ++++++++++++-- .../artifact/AndroidArtifactUtil.java | 50 +++++++++++++++++++ .../android/exportSignedPackage/ApkStep.java | 40 ++------------- 4 files changed, 90 insertions(+), 41 deletions(-) diff --git a/plugins/android/resources/messages/AndroidBundle.properties b/plugins/android/resources/messages/AndroidBundle.properties index 25bd4b10cd19..58e6c4d31fc2 100644 --- a/plugins/android/resources/messages/AndroidBundle.properties +++ b/plugins/android/resources/messages/AndroidBundle.properties @@ -405,4 +405,5 @@ android.launch.draw.9.patch.action=Draw 9 Patch android.facet.settings.include.system.proguard=Include system proguard file file.already.exists.error=File {0} already exists deployment.target.settings.min.sdk.info.message=Only compatible AVDs are shown. See 'uses-sdk' tag in AndroidManifest.xml -android.compilation.warning.circular.app.dependency=Generated fields in {0}.R class in module ''{1}'' won''t be final, because of circular dependency on module ''{2}'' \ No newline at end of file +android.compilation.warning.circular.app.dependency=Generated fields in {0}.R class in module ''{1}'' won''t be final, because of circular dependency on module ''{2}'' +cannot.find.zip.align=The zipalign tool was not found in the SDK.\n\nPlease update to the latest SDK and re-export your application\nor run zipalign manually.\n\nAligning applications allows Android to use application resources\nmore efficiently. \ No newline at end of file diff --git a/plugins/android/src/org/jetbrains/android/compiler/artifact/AndroidApplicationArtifactProperties.java b/plugins/android/src/org/jetbrains/android/compiler/artifact/AndroidApplicationArtifactProperties.java index c7ee3c802239..3df3f323a79f 100644 --- a/plugins/android/src/org/jetbrains/android/compiler/artifact/AndroidApplicationArtifactProperties.java +++ b/plugins/android/src/org/jetbrains/android/compiler/artifact/AndroidApplicationArtifactProperties.java @@ -1,8 +1,10 @@ package org.jetbrains.android.compiler.artifact; +import com.android.sdklib.SdkConstants; import com.intellij.openapi.compiler.CompileContext; import com.intellij.openapi.compiler.CompilerMessageCategory; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.module.Module; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vfs.VfsUtilCore; @@ -14,6 +16,8 @@ import com.intellij.util.xmlb.XmlSerializerUtil; import com.intellij.util.xmlb.annotations.Transient; import org.apache.commons.codec.binary.Base64; import org.jetbrains.android.compiler.AndroidCompileUtil; +import org.jetbrains.android.facet.AndroidFacet; +import org.jetbrains.android.sdk.AndroidPlatform; import org.jetbrains.android.util.AndroidBundle; import org.jetbrains.android.util.AndroidCommonUtils; import org.jetbrains.annotations.NotNull; @@ -44,8 +48,21 @@ public class AndroidApplicationArtifactProperties extends ArtifactProperties pair = getPrivateKeyAndCertificate(context, errorPrefix); + + final AndroidFacet facet = AndroidArtifactUtil.getPackagedFacet(context.getProject(), artifact); + if (facet == null) { + return; + } + final String messagePrefix = "[Artifact '" + artifact.getName() + "'] "; + + final Module module = facet.getModule(); + final AndroidPlatform platform = AndroidPlatform.getInstance(module); + if (platform == null) { + context.addMessage(CompilerMessageCategory.ERROR, messagePrefix + + AndroidBundle.message("android.compilation.error.specify.platform", module.getName()), null, -1, -1); + return; + } + final Pair pair = getPrivateKeyAndCertificate(context, messagePrefix); if (pair == null) { return; } @@ -64,11 +81,26 @@ public class AndroidApplicationArtifactProperties extends ArtifactProperties elementRef = Ref.create(null); + final PackagingElementResolvingContext resolvingContext = ArtifactManager.getInstance(project).getResolvingContext(); + ArtifactUtil + .processPackagingElements(artifact, AndroidFinalPackageElementType.getInstance(), new Processor() { + public boolean process(AndroidFinalPackageElement e) { + elementRef.set(e); + return false; + } + }, resolvingContext, true); + final AndroidFinalPackageElement element = elementRef.get(); + return element != null ? element.getFacet() : null; + } + @Nullable public static AndroidFacet chooseAndroidApplicationModule(@NotNull Project project, @NotNull List modules) { final ChooseModulesDialog dialog = new ChooseModulesDialog(project, modules, "Select Module", @@ -53,4 +78,29 @@ public class AndroidArtifactUtil { } return facet; } + + @Nullable + public static String executeZipAlign(String zipAlignPath, File source, File destination) { + GeneralCommandLine commandLine = new GeneralCommandLine(); + commandLine.setExePath(zipAlignPath); + commandLine.addParameters("-f", "4", source.getAbsolutePath(), destination.getAbsolutePath()); + OSProcessHandler handler; + try { + handler = new OSProcessHandler(commandLine.createProcess(), ""); + } + catch (ExecutionException e) { + return e.getMessage(); + } + final StringBuilder builder = new StringBuilder(); + handler.addProcessListener(new ProcessAdapter() { + @Override + public void onTextAvailable(ProcessEvent event, Key outputType) { + builder.append(event.getText()); + } + }); + handler.startNotify(); + handler.waitFor(); + int exitCode = handler.getProcess().exitValue(); + return exitCode != 0 ? builder.toString() : null; + } } diff --git a/plugins/android/src/org/jetbrains/android/exportSignedPackage/ApkStep.java b/plugins/android/src/org/jetbrains/android/exportSignedPackage/ApkStep.java index 6c25426a7b9e..2e1373608de1 100644 --- a/plugins/android/src/org/jetbrains/android/exportSignedPackage/ApkStep.java +++ b/plugins/android/src/org/jetbrains/android/exportSignedPackage/ApkStep.java @@ -18,11 +18,6 @@ package org.jetbrains.android.exportSignedPackage; import com.android.sdklib.SdkConstants; import com.intellij.CommonBundle; -import com.intellij.execution.ExecutionException; -import com.intellij.execution.configurations.GeneralCommandLine; -import com.intellij.execution.process.OSProcessHandler; -import com.intellij.execution.process.ProcessAdapter; -import com.intellij.execution.process.ProcessEvent; import com.intellij.ide.util.PropertiesComponent; import com.intellij.ide.wizard.CommitStepException; import com.intellij.openapi.application.ApplicationManager; @@ -42,7 +37,6 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ModuleRootManager; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.ui.TextFieldWithBrowseButton; -import com.intellij.openapi.util.Key; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vfs.LocalFileSystem; @@ -50,6 +44,7 @@ import com.intellij.openapi.vfs.VirtualFile; import com.intellij.ui.components.JBLabel; import org.jetbrains.android.compiler.AndroidCompileUtil; import org.jetbrains.android.compiler.AndroidProguardCompiler; +import org.jetbrains.android.compiler.artifact.AndroidArtifactUtil; import org.jetbrains.android.facet.AndroidFacet; import org.jetbrains.android.facet.AndroidFacetConfiguration; import org.jetbrains.android.facet.AndroidRootUtil; @@ -244,7 +239,7 @@ class ApkStep extends ExportSignedPackageWizardStep { if (runZipAlign) { File realDestFile = new File(apkPath); - final String message = executeZipAlign(zipAlignPath, destFile, realDestFile); + final String message = AndroidArtifactUtil.executeZipAlign(zipAlignPath, destFile, realDestFile); if (message != null) { showErrorInDispatchThread(message); return; @@ -254,11 +249,7 @@ class ApkStep extends ExportSignedPackageWizardStep { public void run() { String title = AndroidBundle.message("android.export.package.wizard.title"); if (!runZipAlign) { - Messages.showWarningDialog(myWizard.getProject(), "The zipalign tool was not found in the SDK.\n\n" + - "Please update to the latest SDK and re-export your application\n" + - "or run zipalign manually.\n\n" + - "Aligning applications allows Android to use application resources\n" + - "more efficiently.", title); + Messages.showWarningDialog(myWizard.getProject(), AndroidBundle.message("cannot.find.zip.align"), title); } Messages.showInfoMessage(myWizard.getProject(), AndroidBundle.message("android.export.package.success.message", apkPath), title); } @@ -286,31 +277,6 @@ class ApkStep extends ExportSignedPackageWizardStep { }, ModalityState.NON_MODAL); } - @Nullable - private static String executeZipAlign(String zipAlignPath, File source, File destination) { - GeneralCommandLine commandLine = new GeneralCommandLine(); - commandLine.setExePath(zipAlignPath); - commandLine.addParameters("-f", "4", source.getAbsolutePath(), destination.getAbsolutePath()); - OSProcessHandler handler; - try { - handler = new OSProcessHandler(commandLine.createProcess(), ""); - } - catch (ExecutionException e) { - return e.getMessage(); - } - final StringBuilder builder = new StringBuilder(); - handler.addProcessListener(new ProcessAdapter() { - @Override - public void onTextAvailable(ProcessEvent event, Key outputType) { - builder.append(event.getText()); - } - }); - handler.startNotify(); - handler.waitFor(); - int exitCode = handler.getProcess().exitValue(); - return exitCode != 0 ? builder.toString() : null; - } - @Override protected boolean canFinish() { return true;