diff --git a/android/todo.txt b/android/todo.txt index f064ad351..4c389ed0d 100644 --- a/android/todo.txt +++ b/android/todo.txt @@ -16,7 +16,9 @@ X when returning to android application, sometimes screen stays black X http://code.google.com/p/processing/issues/detail?id=237 X Device Killed or Disconnected Error Message with Libraries X http://code.google.com/p/processing/issues/detail?id=565 -X there's gotta be something we can do to get better ant build messages +X there's gotta be something we can do to get better ant build message +X "Unable to resolve target 'Google...'" when APIs aren't installed +X add an error message that explains what to do earlier X Error 336 Can't run any sketch. @@ -24,9 +26,6 @@ X javac.exe was not included with the download X http://code.google.com/p/processing/issues/detail?id=393 -_ "Unable to resolve target 'Google...'" when APIs aren't installed -_ add an error message that explains what to do - _ canceling an attempt to find the Android SDK leaves no window open _ (Linux and Windows) _ crash when trying to change Android mode void sketch no Android SDK Installed diff --git a/app/src/processing/mode/android/AVD.java b/app/src/processing/mode/android/AVD.java index c36398c58..641a32ace 100644 --- a/app/src/processing/mode/android/AVD.java +++ b/app/src/processing/mode/android/AVD.java @@ -10,7 +10,7 @@ import processing.core.PApplet; public class AVD { - private static final String AVD_CREATE_ERROR = + static private final String AVD_CREATE_ERROR = "An error occurred while running “android create avd”\n" + "to set up the default Android emulator. Make sure that the\n" + "Android SDK is installed properly, and that the Android\n" + @@ -18,6 +18,17 @@ public class AVD { "(Between you and me, occasionally, this error is a red herring,\n" + "and your sketch may be launching shortly.)"; + static private final String AVD_CANNOT_LOAD = + "There is an error with the Processing AVD. This could mean that the\n" + + "Android tools need to be updated, or that the Processing AVD should\n" + + "be deleted (it will automatically re-created the next time you run\n" + + "Processing). Open the Android SDK manager to check for any errors."; + + static private final String AVD_TARGET_MISSING = + "The Google APIs are not installed properly, please re-read\n" + + "the installation instructions for Android Processing from\n" + + "http://android.processing.org and try again."; + static final String DEFAULT_SKIN = "WVGA800"; /** Name of this avd. */ @@ -34,6 +45,7 @@ public class AVD { //AndroidBuild.sdkTarget); static ArrayList avdList; + static ArrayList badList; // static ArrayList skinList; @@ -46,23 +58,31 @@ public class AVD { static protected void list(final AndroidSDK sdk) throws IOException { try { avdList = new ArrayList(); + badList = new ArrayList(); ProcessResult listResult = new ProcessHelper(sdk.getAndroidToolPath(), "list", "avds").execute(); if (listResult.succeeded()) { + boolean badness = false; for (String line : listResult) { String[] m = PApplet.match(line, "\\s+Name\\:\\s+(\\S+)"); if (m != null) { -// System.out.println("Found AVD " + m[1]); - avdList.add(m[1]); -// if (m[1].equals(name)) { -// return true; -// } + if (!badness) { +// System.out.println("good: " + m[1]); + avdList.add(m[1]); + } else { +// System.out.println("bad: " + m[1]); + badList.add(m[1]); + } +// } else { +// System.out.println("nope: " + line); } // "The following Android Virtual Devices could not be loaded:" if (line.contains("could not be loaded:")) { +// System.out.println("starting the bad list"); // System.err.println("Could not list AVDs:"); - System.err.println(listResult); - break; +// System.err.println(listResult); + badness = true; +// break; } } } else { @@ -84,6 +104,17 @@ public class AVD { } return false; } + + + /** Return true if this AVD was on the bad list. */ + protected boolean badness() { + for (String avd : badList) { + if (avd.equals(name)) { + return true; + } + } + return false; + } protected boolean create(final AndroidSDK sdk) throws IOException { @@ -93,47 +124,24 @@ public class AVD { "-n", name, "-t", target, "-c", "64M", "-s", DEFAULT_SKIN -// "-s", DEFAULT_WIDTH + "x" + DEFAULT_HEIGHT }; -// throw new RuntimeException("avd.create() not currently working"); -// final StringWriter outWriter = new StringWriter(); -// final StringWriter errWriter = new StringWriter(); -// final long startTime = System.currentTimeMillis(); -// -// final String prettyCommand = toString(); -// // System.err.println("ProcessHelper: >>>>> " + Thread.currentThread().getId() -// // + " " + prettyCommand); -// final Process process = Runtime.getRuntime().exec(cmd); -// ProcessRegistry.watch(process); -// try { -// String title = PApplet.join(cmd, ' '); -// new StreamPump(process.getInputStream(), "out: " + title).addTarget(outWriter).start(); -// new StreamPump(process.getErrorStream(), "err: " + title).addTarget(errWriter).start(); -// try { -// final int result = process.waitFor(); -// final long time = System.currentTimeMillis() - startTime; -// // System.err.println("ProcessHelper: <<<<< " -// // + Thread.currentThread().getId() + " " + cmd[0] + " (" + time -// // + "ms)"); -// return new ProcessResult(prettyCommand, result, outWriter.toString(), -// errWriter.toString(), time); -// } catch (final InterruptedException e) { -// System.err.println("Interrupted: " + prettyCommand); -// throw e; -// } -// } finally { -// process.destroy(); -// ProcessRegistry.unwatch(process); -// } - final ProcessHelper p = new ProcessHelper(params); try { final ProcessResult createAvdResult = p.execute(); if (createAvdResult.succeeded()) { return true; } - System.err.println(createAvdResult); + if (createAvdResult.toString().contains("Target id is not valid")) { + // They didn't install the Google APIs + Base.showWarning("Android Error", AVD_TARGET_MISSING, null); +// throw new IOException("Missing required SDK components"); + } else { + // Just generally not working + Base.showWarning("Android Error", AVD_CREATE_ERROR, null); +// throw new IOException("Error creating the AVD"); + } + //System.err.println(createAvdResult); } catch (final InterruptedException ie) { } return false; @@ -146,11 +154,14 @@ public class AVD { // System.out.println("the avd exists"); return true; } + if (defaultAVD.badness()) { + Base.showWarning("Android Error", AVD_CANNOT_LOAD, null); + return false; + } if (defaultAVD.create(sdk)) { // System.out.println("the avd was created"); return true; } - Base.showWarning("Android Error", AVD_CREATE_ERROR, null); } catch (final Exception e) { Base.showWarning("Android Error", AVD_CREATE_ERROR, e); } diff --git a/app/src/processing/mode/android/AndroidBuild.java b/app/src/processing/mode/android/AndroidBuild.java index edbf5ba32..8967a2f1d 100644 --- a/app/src/processing/mode/android/AndroidBuild.java +++ b/app/src/processing/mode/android/AndroidBuild.java @@ -57,7 +57,7 @@ class AndroidBuild extends JavaBuild { sdk = mode.getSDK(); coreZipFile = mode.getCoreZipLocation(); - AVD.ensureEclairAVD(sdk); +// AVD.ensureEclairAVD(sdk); } @@ -68,6 +68,14 @@ class AndroidBuild extends JavaBuild { * @throws IOException */ public File build(String target) throws IOException, SketchException { + boolean avd = AVD.ensureEclairAVD(sdk); + if (!avd) { + SketchException se = + new SketchException("Could not create a virtual device for the emulator."); + se.hideStackTrace(); + throw se; + } + this.target = target; File folder = createProject(); if (folder != null) {