From b0144d229730efda3f17f81fd3fc098f6a35dbfc Mon Sep 17 00:00:00 2001 From: Xavier Ducrohet Date: Tue, 25 Jan 2011 10:34:09 -0800 Subject: [PATCH] Android project's output for JDT is now bin/classes/ This matches the bin structure of the Ant build system where the javac output is in bin/classes/ and the Android specific files are in bin/ Also, this will allow us better control of android output files as they won't conflict with javac's output. New projects are created with this setup and existing projects are converted as they are opened. Change-Id: I83339906b0d43d7a988a75927c60b664c183d27f --- .../adt/internal/actions/MultiApkExportAction.java | 14 ++-- .../eclipse/adt/internal/build/BuildHelper.java | 15 ++-- .../build/builders/PostCompilerBuilder.java | 56 ++++++++----- .../adt/internal/project/BaseProjectHelper.java | 43 +++++++++- .../eclipse/adt/internal/project/ExportHelper.java | 93 ++++++++-------------- .../adt/internal/project/FolderDecorator.java | 4 +- .../adt/internal/project/ProjectHelper.java | 2 +- .../android/ide/eclipse/adt/internal/sdk/Sdk.java | 34 ++++++++ .../internal/wizards/export/ProjectCheckPage.java | 22 +---- .../wizards/newproject/NewProjectWizard.java | 7 +- .../src/com/android/sdklib/SdkConstants.java | 2 + 11 files changed, 175 insertions(+), 117 deletions(-) diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/actions/MultiApkExportAction.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/actions/MultiApkExportAction.java index cdf48ad1c..3125c89aa 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/actions/MultiApkExportAction.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/actions/MultiApkExportAction.java @@ -19,6 +19,7 @@ package com.android.ide.eclipse.adt.internal.actions; import com.android.ide.eclipse.adt.AdtPlugin; import com.android.ide.eclipse.adt.AndroidPrintStream; import com.android.ide.eclipse.adt.internal.build.BuildHelper; +import com.android.ide.eclipse.adt.internal.project.BaseProjectHelper; import com.android.ide.eclipse.adt.internal.project.ProjectHelper; import com.android.ide.eclipse.adt.internal.sdk.ProjectState; import com.android.ide.eclipse.adt.internal.sdk.Sdk; @@ -277,19 +278,20 @@ public class MultiApkExportAction implements IObjectActionDelegate { // get the manifest file IFile manifestFile = project.getFile(SdkConstants.FN_ANDROID_MANIFEST_XML); - // get the project bin folder - IFolder projectBinFolder = wsRoot.getFolder(javaProject.getOutputLocation()); - String projectBinFolderPath = projectBinFolder.getLocation().toOSString(); + + // get the project bin folder for android files. + IFolder androidBinFolder = BaseProjectHelper.getAndroidOutputFolder(project); + String androidBinFolderPath = androidBinFolder.getLocation().toOSString(); // package the resources helper.packageResources(manifestFile, libProjects, softVariant != null ? softVariant.getValue() : null, - compositeVersionCode, projectBinFolderPath, pkgName); + compositeVersionCode, androidBinFolderPath, pkgName); apk.setOutputName(softVariant != null ? softVariant.getKey() : null, outputName); // do the final export. - IFile dexFile = projectBinFolder.getFile(SdkConstants.FN_APK_CLASSES_DEX); + IFile dexFile = androidBinFolder.getFile(SdkConstants.FN_APK_CLASSES_DEX); String outputFile = binFolder.getFile(outputName).getLocation().toOSString(); // get the list of referenced projects. @@ -297,7 +299,7 @@ public class MultiApkExportAction implements IObjectActionDelegate { List referencedJavaProjects = BuildHelper.getJavaProjects(javaRefs); helper.finalPackage( - new File(projectBinFolderPath, pkgName).getAbsolutePath(), + new File(androidBinFolderPath, pkgName).getAbsolutePath(), dexFile.getLocation().toOSString(), outputFile, javaProject, 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 5aa9647c8..2ce98e081 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 @@ -364,8 +364,13 @@ public class BuildHelper { } } - public String[] getProjectOutputs() throws CoreException { - IFolder outputFolder = BaseProjectHelper.getOutputFolder(mProject); + /** + * Return a list of the project output for compiled Java code. + * @return + * @throws CoreException + */ + public String[] getProjectJavaOutputs() throws CoreException { + IFolder outputFolder = BaseProjectHelper.getJavaOutputFolder(mProject); // get the list of referenced projects output to add List javaProjects = ProjectHelper.getReferencedProjects(mProject); @@ -373,7 +378,7 @@ public class BuildHelper { // get the project output, and since it's a new list object, just add the outputFolder // of the project directly to it. - List projectOutputs = getProjectOutputs(referencedJavaProjects); + List projectOutputs = getProjectJavaOutputs(referencedJavaProjects); projectOutputs.add(0, outputFolder.getLocation().toOSString()); @@ -403,7 +408,7 @@ public class BuildHelper { String[] compiledPaths; if (includeProjectOutputs) { - String[] projectOutputs = getProjectOutputs(); + String[] projectOutputs = getProjectJavaOutputs(); compiledPaths = new String[libraries.length + projectOutputs.length]; @@ -964,7 +969,7 @@ public class BuildHelper { * @return a new list object containing the output folder paths. * @throws CoreException */ - private List getProjectOutputs(List referencedJavaProjects) + private List getProjectJavaOutputs(List referencedJavaProjects) throws CoreException { ArrayList list = new ArrayList(); 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 1770df952..4b408e6c7 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 @@ -23,10 +23,10 @@ import com.android.ide.eclipse.adt.internal.build.AaptExecException; import com.android.ide.eclipse.adt.internal.build.AaptParser; import com.android.ide.eclipse.adt.internal.build.AaptResultException; import com.android.ide.eclipse.adt.internal.build.BuildHelper; -import com.android.ide.eclipse.adt.internal.build.BuildHelper.ResourceMarker; import com.android.ide.eclipse.adt.internal.build.DexException; import com.android.ide.eclipse.adt.internal.build.Messages; import com.android.ide.eclipse.adt.internal.build.NativeLibInJarException; +import com.android.ide.eclipse.adt.internal.build.BuildHelper.ResourceMarker; import com.android.ide.eclipse.adt.internal.preferences.AdtPrefs; import com.android.ide.eclipse.adt.internal.preferences.AdtPrefs.BuildVerbosity; import com.android.ide.eclipse.adt.internal.project.ApkInstallManager; @@ -116,7 +116,6 @@ public class PostCompilerBuilder extends BaseBuilder { mOutputFolder = javaProject.getOutputLocation(); mSourceFolders = BaseProjectHelper.getSourceClasspaths(javaProject); } catch (JavaModelException e) { - } finally { } } @@ -203,6 +202,20 @@ public class PostCompilerBuilder extends BaseBuilder { // Clear the project of the generic markers removeMarkersFromContainer(project, AdtConstants.MARKER_AAPT_PACKAGE); removeMarkersFromContainer(project, AdtConstants.MARKER_PACKAGING); + + // also remove the files in the output folder (but not the Eclipse output folder). + IFolder javaOutput = BaseProjectHelper.getJavaOutputFolder(project); + IFolder androidOutput = BaseProjectHelper.getAndroidOutputFolder(project); + + if (javaOutput.equals(androidOutput) == false) { + // get the content + IResource[] members = androidOutput.members(); + for (IResource member : members) { + if (member.equals(javaOutput) == false) { + member.delete(true /*force*/, monitor); + } + } + } } // build() returns a list of project from which this project depends for future compilation. @@ -245,9 +258,8 @@ public class PostCompilerBuilder extends BaseBuilder { // Top level check to make sure the build can move forward. abortOnBadSetup(javaProject); - // get the output folder, this method returns the path with a trailing - // separator - IFolder outputFolder = BaseProjectHelper.getOutputFolder(project); + // get the android output folder + IFolder androidOutputFolder = BaseProjectHelper.getAndroidOutputFolder(project); // now we need to get the classpath list List sourceList = BaseProjectHelper.getSourceClasspaths(javaProject); @@ -276,7 +288,7 @@ public class PostCompilerBuilder extends BaseBuilder { mConvertToDex = true; mBuildFinalPackage = true; } else { - dv = new PostCompilerDeltaVisitor(this, sourceList, outputFolder); + dv = new PostCompilerDeltaVisitor(this, sourceList, androidOutputFolder); delta.accept(dv); // save the state @@ -342,7 +354,7 @@ public class PostCompilerBuilder extends BaseBuilder { // remove older packaging markers. removeMarkersFromContainer(javaProject.getProject(), AdtConstants.MARKER_PACKAGING); - if (outputFolder == null) { + if (androidOutputFolder == null) { // mark project and exit markProject(AdtConstants.MARKER_PACKAGING, Messages.Failed_To_Get_Output, IMarker.SEVERITY_ERROR); @@ -377,7 +389,7 @@ public class PostCompilerBuilder extends BaseBuilder { if (mPackageResources == false) { // check the full resource package - tmp = outputFolder.findMember(AdtConstants.FN_RESOURCES_AP_); + tmp = androidOutputFolder.findMember(AdtConstants.FN_RESOURCES_AP_); if (tmp == null || tmp.exists() == false) { mPackageResources = true; mBuildFinalPackage = true; @@ -386,7 +398,7 @@ public class PostCompilerBuilder extends BaseBuilder { // check classes.dex is present. If not we force to recreate it. if (mConvertToDex == false) { - tmp = outputFolder.findMember(SdkConstants.FN_APK_CLASSES_DEX); + tmp = androidOutputFolder.findMember(SdkConstants.FN_APK_CLASSES_DEX); if (tmp == null || tmp.exists() == false) { mConvertToDex = true; mBuildFinalPackage = true; @@ -396,7 +408,7 @@ public class PostCompilerBuilder extends BaseBuilder { // also check the final file(s)! String finalPackageName = ProjectHelper.getApkFilename(project, null /*config*/); if (mBuildFinalPackage == false) { - tmp = outputFolder.findMember(finalPackageName); + tmp = androidOutputFolder.findMember(finalPackageName); if (tmp == null || (tmp instanceof IFile && tmp.exists() == false)) { String msg = String.format(Messages.s_Missing_Repackaging, finalPackageName); @@ -410,7 +422,7 @@ public class PostCompilerBuilder extends BaseBuilder { // because they are missing // refresh the output directory first - IContainer ic = outputFolder.getParent(); + IContainer ic = androidOutputFolder.getParent(); if (ic != null) { ic.refreshLocal(IResource.DEPTH_ONE, monitor); } @@ -443,18 +455,18 @@ public class PostCompilerBuilder extends BaseBuilder { return allRefProjects; } - IPath binLocation = outputFolder.getLocation(); - if (binLocation == null) { + IPath androidBinLocation = androidOutputFolder.getLocation(); + if (androidBinLocation == null) { markProject(AdtConstants.MARKER_PACKAGING, Messages.Output_Missing, IMarker.SEVERITY_ERROR); return allRefProjects; } - String osBinPath = binLocation.toOSString(); + String osAndroidBinPath = androidBinLocation.toOSString(); // Remove the old .apk. // This make sure that if the apk is corrupted, then dx (which would attempt // to open it), will not fail. - String osFinalPackagePath = osBinPath + File.separator + finalPackageName; + String osFinalPackagePath = osAndroidBinPath + File.separator + finalPackageName; File finalPackage = new File(osFinalPackagePath); // if delete failed, this is not really a problem, as the final package generation @@ -469,7 +481,7 @@ public class PostCompilerBuilder extends BaseBuilder { try { helper.packageResources(manifestFile, libProjects, null /*resfilter*/, - 0 /*versionCode */, osBinPath, + 0 /*versionCode */, osAndroidBinPath, AdtConstants.FN_RESOURCES_AP_); } catch (AaptExecException e) { BaseProjectHelper.markResource(project, AdtConstants.MARKER_PACKAGING, @@ -501,14 +513,16 @@ public class PostCompilerBuilder extends BaseBuilder { saveProjectBooleanProperty(PROPERTY_PACKAGE_RESOURCES, mPackageResources); } + String classesDexPath = osAndroidBinPath + File.separator + + SdkConstants.FN_APK_CLASSES_DEX; + // then we check if we need to package the .class into classes.dex if (mConvertToDex) { try { String[] dxInputPaths = helper.getCompiledCodePaths( true /*includeProjectOutputs*/, mResourceMarker); - helper.executeDx(javaProject, dxInputPaths, osBinPath + File.separator + - SdkConstants.FN_APK_CLASSES_DEX); + helper.executeDx(javaProject, dxInputPaths, classesDexPath); } catch (DexException e) { String message = e.getMessage(); @@ -539,11 +553,9 @@ public class PostCompilerBuilder extends BaseBuilder { // and classes.dex. // This is the default package with all the resources. - String classesDexPath = osBinPath + File.separator + - SdkConstants.FN_APK_CLASSES_DEX; try { helper.finalDebugPackage( - osBinPath + File.separator + AdtConstants.FN_RESOURCES_AP_, + osAndroidBinPath + File.separator + AdtConstants.FN_RESOURCES_AP_, classesDexPath, osFinalPackagePath, javaProject, libProjects, referencedJavaProjects, mResourceMarker); } catch (KeytoolException e) { @@ -602,7 +614,7 @@ public class PostCompilerBuilder extends BaseBuilder { // we are done. // get the resource to bin - outputFolder.refreshLocal(IResource.DEPTH_ONE, monitor); + androidOutputFolder.refreshLocal(IResource.DEPTH_ONE, monitor); // build has been done. reset the state of the builder mBuildFinalPackage = false; diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/BaseProjectHelper.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/BaseProjectHelper.java index 8c4d08d7d..84f98a304 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/BaseProjectHelper.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/BaseProjectHelper.java @@ -444,13 +444,14 @@ public final class BaseProjectHelper { } /** - * Returns the {@link IFolder} representing the output for the project. + * Returns the {@link IFolder} representing the output for the project for Android specific + * files. *

* The project must be a java project and be opened, or the method will return null. * @param project the {@link IProject} * @return an IFolder item or null. */ - public final static IFolder getOutputFolder(IProject project) { + public final static IFolder getJavaOutputFolder(IProject project) { try { if (project.isOpen() && project.hasNature(JavaCore.NATURE_ID)) { // get a java project from the normal project object @@ -470,4 +471,42 @@ public final class BaseProjectHelper { } return null; } + + /** + * Returns the {@link IFolder} representing the output for the project for compiled Java + * files. + *

+ * The project must be a java project and be opened, or the method will return null. + * @param project the {@link IProject} + * @return an IFolder item or null. + */ + public final static IFolder getAndroidOutputFolder(IProject project) { + try { + if (project.isOpen() && project.hasNature(JavaCore.NATURE_ID)) { + // get a java project from the normal project object + IJavaProject javaProject = JavaCore.create(project); + + IPath path = javaProject.getOutputLocation(); + IWorkspaceRoot wsRoot = ResourcesPlugin.getWorkspace().getRoot(); + IResource outputResource = wsRoot.findMember(path); + + if (outputResource != null) { // really shouldn't happen + // if the output folder is directly a child of the project, + // then use it directly. + if (outputResource.getParent().equals(project)) { + return (IFolder) outputResource; + } + + // otherwise returns the parent folder of the java output folder. + return (IFolder) outputResource.getParent(); + } + } + } catch (JavaModelException e) { + // Let's do nothing and return null + } catch (CoreException e) { + // Let's do nothing and return null + } + return null; + } + } 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 f5316674f..020d1bc2e 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 @@ -34,18 +34,15 @@ import com.android.sdklib.internal.project.ProjectProperties; import com.android.sdklib.xml.AndroidManifest; import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IFolder; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.JavaCore; -import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.FileDialog; @@ -160,7 +157,7 @@ public final class ExportHelper { if (runProguard) { // the output of the main project (and any java-only project dependency) - String[] projectOutputs = helper.getProjectOutputs(); + String[] projectOutputs = helper.getProjectJavaOutputs(); // create a jar from the output of these projects File inputJar = File.createTempFile(TEMP_PREFIX, AdtConstants.DOT_JAR); @@ -268,64 +265,44 @@ public final class ExportHelper { public static void exportUnsignedReleaseApk(final IProject project) { Shell shell = Display.getCurrent().getActiveShell(); - // get the java project to get the output directory - IFolder outputFolder = BaseProjectHelper.getOutputFolder(project); - if (outputFolder != null) { - IPath binLocation = outputFolder.getLocation(); + // create a default file name for the apk. + String fileName = project.getName() + AdtConstants.DOT_ANDROID_PACKAGE; - // make the full path to the package - String fileName = project.getName() + AdtConstants.DOT_ANDROID_PACKAGE; + // Pop up the file save window to get the file location + FileDialog fileDialog = new FileDialog(shell, SWT.SAVE); - File file = new File(binLocation.toOSString() + File.separator + fileName); + fileDialog.setText("Export Project"); + fileDialog.setFileName(fileName); - if (file.exists() == false || file.isFile() == false) { - MessageDialog.openError(Display.getCurrent().getActiveShell(), - "Android IDE Plug-in", - String.format("Failed to export %1$s: %2$s doesn't exist!", - project.getName(), file.getPath())); - return; - } - - // ok now pop up the file save window - FileDialog fileDialog = new FileDialog(shell, SWT.SAVE); - - fileDialog.setText("Export Project"); - fileDialog.setFileName(fileName); - - final String saveLocation = fileDialog.open(); - if (saveLocation != null) { - new Job("Android Release Export") { - @Override - protected IStatus run(IProgressMonitor monitor) { - try { - exportReleaseApk(project, - new File(saveLocation), - null, //key - null, //certificate - monitor); - - // this is unsigned export. Let's tell the developers to run zip align - AdtPlugin.displayWarning("Android IDE Plug-in", String.format( - "An unsigned package of the application was saved at\n%1$s\n\n" + - "Before publishing the application you will need to:\n" + - "- Sign the application with your release key,\n" + - "- run zipalign on the signed package. ZipAlign is located in /tools/\n\n" + - "Aligning applications allows Android to use application resources\n" + - "more efficiently.", saveLocation)); - - return Status.OK_STATUS; - } catch (CoreException e) { - AdtPlugin.displayError("Android IDE Plug-in", String.format( - "Error exporting application:\n\n%1$s", e.getMessage())); - return e.getStatus(); - } + final String saveLocation = fileDialog.open(); + if (saveLocation != null) { + new Job("Android Release Export") { + @Override + protected IStatus run(IProgressMonitor monitor) { + try { + exportReleaseApk(project, + new File(saveLocation), + null, //key + null, //certificate + monitor); + + // this is unsigned export. Let's tell the developers to run zip align + AdtPlugin.displayWarning("Android IDE Plug-in", String.format( + "An unsigned package of the application was saved at\n%1$s\n\n" + + "Before publishing the application you will need to:\n" + + "- Sign the application with your release key,\n" + + "- run zipalign on the signed package. ZipAlign is located in /tools/\n\n" + + "Aligning applications allows Android to use application resources\n" + + "more efficiently.", saveLocation)); + + return Status.OK_STATUS; + } catch (CoreException e) { + AdtPlugin.displayError("Android IDE Plug-in", String.format( + "Error exporting application:\n\n%1$s", e.getMessage())); + return e.getStatus(); } - }.schedule(); - } - } else { - MessageDialog.openError(shell, "Android IDE Plug-in", - String.format("Failed to export %1$s: Could not get project output location", - project.getName())); + } + }.schedule(); } } diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/FolderDecorator.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/FolderDecorator.java index 394338b07..4fd3c3559 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/FolderDecorator.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/FolderDecorator.java @@ -16,8 +16,8 @@ package com.android.ide.eclipse.adt.internal.project; -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.sdk.Sdk; import com.android.sdklib.SdkConstants; @@ -66,6 +66,8 @@ public class FolderDecorator implements ILightweightLabelDecorator { doDecoration(decoration, " [Generated Java Files]"); } else if (name.equals(SdkConstants.FD_NATIVE_LIBS)) { doDecoration(decoration, null); + } else if (name.equals(SdkConstants.FD_OUTPUT)) { + doDecoration(decoration, null); } else if (folder.isLinked() && Sdk.CREATOR_ADT.equals( ProjectHelper.loadStringProperty(folder, Sdk.PROP_CREATOR))) { doDecoration(decoration, " [Android Library]"); diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/ProjectHelper.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/ProjectHelper.java index 97dd68e7c..2804bac21 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/ProjectHelper.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/ProjectHelper.java @@ -772,7 +772,7 @@ public final class ProjectHelper { */ public static IFile getApplicationPackage(IProject project) { // get the output folder - IFolder outputLocation = BaseProjectHelper.getOutputFolder(project); + IFolder outputLocation = BaseProjectHelper.getAndroidOutputFolder(project); if (outputLocation == null) { AdtPlugin.printErrorToConsole(project, diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/Sdk.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/Sdk.java index 33d49a899..e704c05e4 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/Sdk.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/Sdk.java @@ -838,6 +838,40 @@ public final class Sdk { // of which can happen here since we're processing a Project opened event. } + // convert older projects which use bin as the eclipse output folder into projects + // using bin/classes + IFolder javaOutput = BaseProjectHelper.getJavaOutputFolder(openedProject); + IFolder androidOutput = BaseProjectHelper.getAndroidOutputFolder(openedProject); + if (javaOutput.equals(androidOutput)) { + final IFolder newJavaOutput = javaOutput.getFolder(SdkConstants.FD_CLASSES_OUTPUT); + if (newJavaOutput.exists() == false) { + Job job = new Job("Project bin convertion") { + @Override + protected IStatus run(IProgressMonitor monitor) { + try { + newJavaOutput.create(true /*force*/, true /*local*/, + monitor); + + // set the java output to this project. + IJavaProject javaProject = JavaCore.create(openedProject); + javaProject.setOutputLocation(newJavaOutput.getFullPath(), + monitor); + + openedProject.build(IncrementalProjectBuilder.CLEAN_BUILD, monitor); + } catch (CoreException e) { + return e.getStatus(); + } + + return Status.OK_STATUS; + } + }; + job.setPriority(Job.BUILD); // build jobs are run after other interactive jobs + job.schedule(); + + } + } + + ProjectState openedState = getProjectState(openedProject); if (openedState != null) { if (openedState.hasLibraries()) { diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/export/ProjectCheckPage.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/export/ProjectCheckPage.java index f7978fb81..9ebdfbbdf 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/export/ProjectCheckPage.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/export/ProjectCheckPage.java @@ -40,7 +40,6 @@ import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Text; @@ -55,7 +54,6 @@ final class ProjectCheckPage extends ExportWizardPage { private final static String IMG_WARNING = "warning.png"; //$NON-NLS-1$ private final ExportWizard mWizard; - private Display mDisplay; private Image mError; private Image mWarning; private boolean mHasMessage = false; @@ -76,7 +74,6 @@ final class ProjectCheckPage extends ExportWizardPage { public void createControl(Composite parent) { mProjectChooserHelper = new ProjectChooserHelper(parent.getShell(), new NonLibraryProjectOnlyFilter()); - mDisplay = parent.getDisplay(); GridLayout gl = null; GridData gd = null; @@ -170,27 +167,12 @@ final class ProjectCheckPage extends ExportWizardPage { } // check the project output - IFolder outputIFolder = BaseProjectHelper.getOutputFolder(project); - if (outputIFolder != null) { - String outputOsPath = outputIFolder.getLocation().toOSString(); - String apkFilePath = outputOsPath + File.separator + project.getName() + - AdtConstants.DOT_ANDROID_PACKAGE; - - File f = new File(apkFilePath); - try { - f.createNewFile(); - } catch (IOException e) { - addError(mErrorComposite, - String.format("Could not open %1$s/%2$s/%1$s%3$s for writing!", - project.getName(), outputIFolder.getName(), - AdtConstants.DOT_ANDROID_PACKAGE)); - } - } else { + IFolder outputIFolder = BaseProjectHelper.getJavaOutputFolder(project); + if (outputIFolder == null) { addError(mErrorComposite, "Unable to get the output folder of the project!"); } - // project is an android project, we check the debuggable attribute. ManifestData manifestData = AndroidManifestHelper.parseForData(project); Boolean debuggable = null; diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/NewProjectWizard.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/NewProjectWizard.java index 9a3f572db..64896169b 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/NewProjectWizard.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/NewProjectWizard.java @@ -136,6 +136,9 @@ public class NewProjectWizard extends Wizard implements INewWizard { private static final String BIN_DIRECTORY = SdkConstants.FD_OUTPUT + AdtConstants.WS_SEP; + private static final String BIN_CLASSES_DIRECTORY = + SdkConstants.FD_OUTPUT + AdtConstants.WS_SEP + + SdkConstants.FD_CLASSES_OUTPUT + AdtConstants.WS_SEP; private static final String RES_DIRECTORY = SdkConstants.FD_RESOURCES + AdtConstants.WS_SEP; private static final String ASSETS_DIRECTORY = @@ -190,7 +193,7 @@ public class NewProjectWizard extends Wizard implements INewWizard { private static final String STRING_HELLO_WORLD = "hello"; //$NON-NLS-1$ private static final String[] DEFAULT_DIRECTORIES = new String[] { - BIN_DIRECTORY, RES_DIRECTORY, ASSETS_DIRECTORY }; + BIN_DIRECTORY, BIN_CLASSES_DIRECTORY, RES_DIRECTORY, ASSETS_DIRECTORY }; private static final String[] RES_DIRECTORIES = new String[] { DRAWABLE_DIRECTORY, LAYOUT_DIRECTORY, VALUES_DIRECTORY }; private static final String[] RES_DENSITY_ENABLED_DIRECTORIES = new String[] { @@ -706,7 +709,7 @@ public class NewProjectWizard extends Wizard implements INewWizard { monitor); // Set output location - javaProject.setOutputLocation(project.getFolder(BIN_DIRECTORY).getFullPath(), + javaProject.setOutputLocation(project.getFolder(BIN_CLASSES_DIRECTORY).getFullPath(), monitor); } diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/SdkConstants.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/SdkConstants.java index 8f5b69ce6..713e8a844 100644 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/SdkConstants.java +++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/SdkConstants.java @@ -182,6 +182,8 @@ public final class SdkConstants { public final static String FD_APK_NATIVE_LIBS = "lib"; //$NON-NLS-1$ /** Default output folder name, i.e. "bin" */ public final static String FD_OUTPUT = "bin"; //$NON-NLS-1$ + /** Classes output folder name, i.e. "classes" */ + public final static String FD_CLASSES_OUTPUT = "classes"; //$NON-NLS-1$ /** proguard output folder for mapping, etc.. files */ public final static String FD_PROGUARD = "proguard"; //$NON-NLS-1$ -- 2.11.0