mirror of
https://github.com/processing/processing4.git
synced 2026-06-16 04:26:26 +02:00
adding export, cleaning up
This commit is contained in:
@@ -22,22 +22,16 @@
|
||||
package processing.app.tools.android;
|
||||
|
||||
import java.awt.Frame;
|
||||
import java.io.File;
|
||||
import java.io.*;
|
||||
import java.net.URL;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import processing.app.Base;
|
||||
import processing.app.Editor;
|
||||
import processing.app.Sketch;
|
||||
import processing.app.debug.Runner;
|
||||
import processing.app.debug.RunnerException;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.*;
|
||||
import java.util.regex.*;
|
||||
|
||||
import processing.app.*;
|
||||
import processing.app.debug.*;
|
||||
import processing.app.tools.Tool;
|
||||
|
||||
import processing.core.PApplet;
|
||||
|
||||
// http://dl.google.com/android/repository/repository.xml
|
||||
@@ -118,17 +112,17 @@ public class AndroidTool implements Tool, DeviceListener {
|
||||
return true;
|
||||
}
|
||||
|
||||
public Editor getEditor() {
|
||||
return editor;
|
||||
}
|
||||
// public Editor getEditor() {
|
||||
// return editor;
|
||||
// }
|
||||
|
||||
public Sketch getSketch() {
|
||||
return editor.getSketch();
|
||||
}
|
||||
// public Sketch getSketch() {
|
||||
// return editor.getSketch();
|
||||
// }
|
||||
|
||||
public Build getBuilder() {
|
||||
return build;
|
||||
}
|
||||
// public Build getBuilder() {
|
||||
// return build;
|
||||
// }
|
||||
|
||||
// if user asks for 480x320, 320x480, 854x480 etc, then launch like that
|
||||
// though would need to query the emulator to see if it can do that
|
||||
@@ -165,11 +159,12 @@ public class AndroidTool implements Tool, DeviceListener {
|
||||
} catch (final TimeoutException expected) {
|
||||
}
|
||||
}
|
||||
editor
|
||||
.statusError("No, on second thought, I'm giving up on waiting for that device to show up.");
|
||||
editor.statusError("No, on second thought, I'm giving up " +
|
||||
"on waiting for that device to show up.");
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
private volatile AndroidDevice lastRunDevice = null;
|
||||
|
||||
private void runSketchOnDevice(final Future<AndroidDevice> deviceFuture)
|
||||
@@ -179,8 +174,8 @@ public class AndroidTool implements Tool, DeviceListener {
|
||||
"Building and launching...",
|
||||
"Creating project...");
|
||||
try {
|
||||
final Build build = getBuilder();
|
||||
if (!build.createProject()) {
|
||||
// final Build build = getBuilder();
|
||||
if (build.createProject() != null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
@@ -232,6 +227,119 @@ public class AndroidTool implements Tool, DeviceListener {
|
||||
monitor.close();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void buildReleaseForExport() throws Cancelled {
|
||||
final IndeterminateProgressMonitor monitor =
|
||||
new IndeterminateProgressMonitor(editor,
|
||||
"Building and exporting...",
|
||||
"Creating project...");
|
||||
try {
|
||||
File tempFolder = build.createProject();
|
||||
if (tempFolder == null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
if (monitor.isCanceled()) {
|
||||
throw new Cancelled();
|
||||
}
|
||||
monitor.setNote("Building release version...");
|
||||
if (!build.antBuild("release")) {
|
||||
return;
|
||||
}
|
||||
System.out.println("build like.");
|
||||
|
||||
if (monitor.isCanceled()) {
|
||||
throw new Cancelled();
|
||||
}
|
||||
|
||||
// If things built successfully, copy the contents to the export folder
|
||||
File exportFolder = build.createExportFolder();
|
||||
// Base.openFolder(tempFolder);
|
||||
// System.out.println("folder will be " + exportFolder);
|
||||
if (exportFolder != null) {
|
||||
Base.copyDir(tempFolder, exportFolder);
|
||||
editor.statusNotice("Done with export.");
|
||||
Base.openFolder(exportFolder);
|
||||
} else {
|
||||
System.err.println("bad copy");
|
||||
editor.statusError("Could not copy files to export folder.");
|
||||
}
|
||||
|
||||
} catch (IOException e) {
|
||||
System.err.println("bad copy ioe");
|
||||
editor.statusError(e);
|
||||
|
||||
} finally {
|
||||
build.cleanup();
|
||||
}
|
||||
} finally {
|
||||
monitor.close();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void buildReleaseForDevice(final Future<AndroidDevice> deviceFuture) throws Cancelled {
|
||||
final IndeterminateProgressMonitor monitor =
|
||||
new IndeterminateProgressMonitor(editor,
|
||||
"Building and running...",
|
||||
"Creating project...");
|
||||
try {
|
||||
File tempFolder = build.createProject();
|
||||
if (tempFolder == null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
if (monitor.isCanceled()) {
|
||||
throw new Cancelled();
|
||||
}
|
||||
monitor.setNote("Building...");
|
||||
if (!build.antBuild("release")) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (monitor.isCanceled()) {
|
||||
throw new Cancelled();
|
||||
}
|
||||
|
||||
monitor.setNote("Waiting for device to become available...");
|
||||
final AndroidDevice device = waitForDevice(deviceFuture, monitor);
|
||||
if (device == null || !device.isAlive()) {
|
||||
editor.statusError("Device killed or disconnected.");
|
||||
return;
|
||||
}
|
||||
|
||||
device.addListener(this);
|
||||
|
||||
if (monitor.isCanceled()) {
|
||||
throw new Cancelled();
|
||||
}
|
||||
monitor.setNote("Installing sketch on " + device.getId());
|
||||
if (!device.installApp(build.getPathForAPK("debug"), editor)) {
|
||||
editor.statusError("Device killed or disconnected.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (monitor.isCanceled()) {
|
||||
throw new Cancelled();
|
||||
}
|
||||
monitor.setNote("Starting sketch on " + device.getId());
|
||||
if (startSketch(device)) {
|
||||
editor.statusNotice("Sketch launched on the "
|
||||
+ (device.isEmulator() ? "emulator" : "phone") + ".");
|
||||
} else {
|
||||
editor.statusError("Could not start the sketch.");
|
||||
}
|
||||
|
||||
lastRunDevice = device;
|
||||
} finally {
|
||||
build.cleanup();
|
||||
}
|
||||
} finally {
|
||||
monitor.close();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static final Pattern LOCATION =
|
||||
Pattern.compile("\\(([^:]+):(\\d+)\\)");
|
||||
@@ -323,9 +431,15 @@ public class AndroidTool implements Tool, DeviceListener {
|
||||
|
||||
/**
|
||||
* Create a release build of the sketch and have its apk files ready.
|
||||
* If users want a debug build, they can do that from the command line.
|
||||
*/
|
||||
private static class ExportHandler implements Runnable {
|
||||
private class ExportHandler implements Runnable {
|
||||
public void run() {
|
||||
try {
|
||||
buildReleaseForExport();
|
||||
} catch (final Cancelled ok) {
|
||||
editor.statusNotice("Cancelled.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -333,8 +447,13 @@ public class AndroidTool implements Tool, DeviceListener {
|
||||
* Create a release build of the sketch and install its apk files on the
|
||||
* attached device.
|
||||
*/
|
||||
private static class ExportAppHandler implements Runnable {
|
||||
private class ExportAppHandler implements Runnable {
|
||||
public void run() {
|
||||
try {
|
||||
buildReleaseForDevice(AndroidEnvironment.getInstance().getHardware());
|
||||
} catch (final Cancelled ok) {
|
||||
editor.statusNotice("Cancelled.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,27 +1,18 @@
|
||||
package processing.app.tools.android;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FilenameFilter;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.PrintStream;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.*;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import org.apache.tools.ant.BuildException;
|
||||
import org.apache.tools.ant.DefaultLogger;
|
||||
import org.apache.tools.ant.Project;
|
||||
import org.apache.tools.ant.ProjectHelper;
|
||||
import processing.app.Base;
|
||||
import processing.app.Editor;
|
||||
import processing.app.Preferences;
|
||||
import processing.app.Sketch;
|
||||
import java.util.*;
|
||||
|
||||
import org.apache.tools.ant.*;
|
||||
|
||||
import processing.app.*;
|
||||
import processing.app.exec.*;
|
||||
import processing.app.debug.RunnerException;
|
||||
import processing.app.preproc.PdePreprocessor;
|
||||
import processing.core.PApplet;
|
||||
|
||||
|
||||
class Build {
|
||||
static SimpleDateFormat dateFormat = new SimpleDateFormat("yyMMdd.HHmm");
|
||||
|
||||
@@ -32,7 +23,7 @@ class Build {
|
||||
|
||||
String className;
|
||||
|
||||
File androidFolder;
|
||||
File tempBuildFolder;
|
||||
|
||||
File buildFile;
|
||||
|
||||
@@ -44,6 +35,7 @@ class Build {
|
||||
}
|
||||
|
||||
// TODO this needs to be a generic function inside Sketch or elsewhere
|
||||
/*
|
||||
protected int[] getSketchSize() {
|
||||
int wide = AVD.DEFAULT_WIDTH;
|
||||
int high = AVD.DEFAULT_HEIGHT;
|
||||
@@ -81,19 +73,21 @@ class Build {
|
||||
}
|
||||
return new int[] { wide, high };
|
||||
}
|
||||
*/
|
||||
|
||||
public boolean createProject() {
|
||||
|
||||
public File createProject() {
|
||||
final Sketch sketch = editor.getSketch();
|
||||
|
||||
try {
|
||||
androidFolder = createAndroidBuildFolder(sketch);
|
||||
tempBuildFolder = createTempBuildFolder(sketch);
|
||||
} catch (final IOException e) {
|
||||
editor.statusError(e);
|
||||
return false;
|
||||
return null;
|
||||
}
|
||||
|
||||
// Create the 'src' folder with the preprocessed code.
|
||||
final File srcFolder = new File(androidFolder, "src");
|
||||
final File srcFolder = new File(tempBuildFolder, "src");
|
||||
|
||||
try {
|
||||
final File javaFolder = mkdirs(srcFolder, getPackageName().replace('.',
|
||||
@@ -111,17 +105,17 @@ class Build {
|
||||
sketch.prepare();
|
||||
className = sketch.preprocess(buildPath, new Preproc(sketch.getName()));
|
||||
if (className != null) {
|
||||
final File androidXML = new File(androidFolder, "AndroidManifest.xml");
|
||||
final File androidXML = new File(tempBuildFolder, "AndroidManifest.xml");
|
||||
writeAndroidManifest(androidXML, sketch.getName(), className);
|
||||
writeBuildProps(new File(androidFolder, "build.properties"));
|
||||
buildFile = new File(androidFolder, "build.xml");
|
||||
writeBuildProps(new File(tempBuildFolder, "build.properties"));
|
||||
buildFile = new File(tempBuildFolder, "build.xml");
|
||||
writeBuildXML(buildFile, sketch.getName());
|
||||
writeDefaultProps(new File(androidFolder, "default.properties"));
|
||||
writeLocalProps(new File(androidFolder, "local.properties"));
|
||||
writeRes(new File(androidFolder, "res"), className);
|
||||
writeDefaultProps(new File(tempBuildFolder, "default.properties"));
|
||||
writeLocalProps(new File(tempBuildFolder, "local.properties"));
|
||||
writeRes(new File(tempBuildFolder, "res"), className);
|
||||
|
||||
final File libsFolder = mkdirs(androidFolder, "libs");
|
||||
final File assetsFolder = mkdirs(androidFolder, "assets");
|
||||
final File libsFolder = mkdirs(tempBuildFolder, "libs");
|
||||
final File assetsFolder = mkdirs(tempBuildFolder, "assets");
|
||||
|
||||
final InputStream input = PApplet.createInput(AndroidTool
|
||||
.getCoreZipFile());
|
||||
@@ -144,18 +138,19 @@ class Build {
|
||||
}
|
||||
} catch (final RunnerException e) {
|
||||
editor.statusError(e);
|
||||
return false;
|
||||
return null;
|
||||
} catch (final IOException e) {
|
||||
editor.statusError(e);
|
||||
return false;
|
||||
return null;
|
||||
}
|
||||
return true;
|
||||
return tempBuildFolder;
|
||||
}
|
||||
|
||||
/**
|
||||
* The Android dex util pukes on paths containing spaces, which will happen
|
||||
* most of the time on Windows, since Processing sketches wind up in
|
||||
* "My Documents". Therefore, build android in a temp file.
|
||||
* http://code.google.com/p/android/issues/detail?id=4567
|
||||
*
|
||||
* TODO: better would be to retrieve the 8.3 name for the sketch folder!
|
||||
*
|
||||
@@ -163,7 +158,7 @@ class Build {
|
||||
* @return A folder in which to build the android sketch
|
||||
* @throws IOException
|
||||
*/
|
||||
private File createAndroidBuildFolder(final Sketch sketch) throws IOException {
|
||||
private File createTempBuildFolder(final Sketch sketch) throws IOException {
|
||||
final File tmp = File.createTempFile("android", ".pde");
|
||||
if (!(tmp.delete() && tmp.mkdir())) {
|
||||
throw new IOException("Cannot create temp dir " + tmp
|
||||
@@ -171,15 +166,64 @@ class Build {
|
||||
}
|
||||
return tmp;
|
||||
}
|
||||
|
||||
|
||||
protected File createExportFolder() throws IOException {
|
||||
Sketch sketch = editor.getSketch();
|
||||
// Create the 'android' build folder, and move any existing version out.
|
||||
File androidFolder = new File(sketch.getFolder(), "android");
|
||||
if (androidFolder.exists()) {
|
||||
Date mod = new Date(androidFolder.lastModified());
|
||||
File dest = new File(sketch.getFolder(), "android." + dateFormat.format(mod));
|
||||
boolean result = androidFolder.renameTo(dest);
|
||||
if (!result) {
|
||||
ProcessHelper mv;
|
||||
ProcessResult pr;
|
||||
try {
|
||||
System.err.println("createProject renameTo() failed, resorting to mv/move instead.");
|
||||
mv = new ProcessHelper("mv", androidFolder.getAbsolutePath(), dest.getAbsolutePath());
|
||||
pr = mv.execute();
|
||||
|
||||
} catch (IOException e) {
|
||||
editor.statusError(e);
|
||||
return null;
|
||||
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
if (!pr.succeeded()) {
|
||||
System.err.println(pr.getStderr());
|
||||
Base.showWarning("Failed to rename",
|
||||
"Could not rename the old “android” build folder.\n" +
|
||||
"Please delete, close, or rename the folder\n" +
|
||||
androidFolder.getAbsolutePath() + "\n" +
|
||||
"and try again." , null);
|
||||
Base.openFolder(sketch.getFolder());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
boolean result = androidFolder.mkdirs();
|
||||
if (!result) {
|
||||
Base.showWarning("Folders, folders, folders",
|
||||
"Could not create the necessary folders to build.\n" +
|
||||
"Perhaps you have some file permissions to sort out?", null);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return androidFolder;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @param target
|
||||
* "debug" or "release"
|
||||
* @param target "debug" or "release"
|
||||
*/
|
||||
boolean antBuild(final String target) {
|
||||
final Project p = new Project();
|
||||
p.setUserProperty("ant.file", buildFile.getAbsolutePath()
|
||||
.replace('\\', '/'));
|
||||
String path = buildFile.getAbsolutePath().replace('\\', '/');
|
||||
p.setUserProperty("ant.file", path);
|
||||
|
||||
// deals with a problem where javac error messages weren't coming through
|
||||
p.setUserProperty("build.compiler", "extJavac");
|
||||
@@ -319,7 +363,7 @@ class Build {
|
||||
|
||||
String getPathForAPK(final String target) {
|
||||
final Sketch sketch = editor.getSketch();
|
||||
final File apkFile = new File(androidFolder, "bin/" + sketch.getName()
|
||||
final File apkFile = new File(tempBuildFolder, "bin/" + sketch.getName()
|
||||
+ "-" + target + ".apk");
|
||||
return apkFile.getAbsolutePath();
|
||||
}
|
||||
@@ -365,8 +409,8 @@ class Build {
|
||||
//"java.util.zip.*", "java.util.regex.*" // not necessary w/ newer i/o
|
||||
};
|
||||
|
||||
Preferences.set("android.preproc.imports.list", PApplet.join(
|
||||
androidImports, ","));
|
||||
Preferences.set("android.preproc.imports.list",
|
||||
PApplet.join(androidImports, ","));
|
||||
|
||||
return androidImports;
|
||||
}
|
||||
@@ -606,7 +650,7 @@ class Build {
|
||||
}
|
||||
|
||||
public void cleanup() {
|
||||
rm(androidFolder);
|
||||
rm(tempBuildFolder);
|
||||
}
|
||||
|
||||
private void rm(final File f) {
|
||||
|
||||
@@ -58,6 +58,7 @@ class EmulatorController {
|
||||
// beginning execution of the emulator, so we are now officially "Launched"
|
||||
setState(State.WAITING_FOR_BOOT);
|
||||
|
||||
// TODO need to suppress this warning on OS X
|
||||
// 2010-04-13 15:26:56.380 emulator[91699:903] Warning once: This
|
||||
// application, or a library it uses, is using NSQuickDrawView, which has
|
||||
// been deprecated. Apps should cease use of QuickDraw and move to Quartz.
|
||||
|
||||
Reference in New Issue
Block a user