Skip to content

Commit 7941f07

Browse files
committed
gradle build export of fragment app
1 parent 87f42d0 commit 7941f07

File tree

6 files changed

+126
-225
lines changed

6 files changed

+126
-225
lines changed

mode/gradlew.zip

-1 Bytes
Binary file not shown.

src/processing/mode/android/AndroidBuild.java

Lines changed: 56 additions & 223 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,12 @@ class AndroidBuild extends JavaBuild {
6666
static private final String XML_WALLPAPER_TEMPLATE = "XMLWallpaper.xml.tmpl";
6767
static private final String STRINGS_WALLPAPER_TEMPLATE = "StringsWallpaper.xml.tmpl";
6868
static private final String XML_WATCHFACE_TEMPLATE = "XMLWatchFace.xml.tmpl";
69-
static private final String BUILD_TEMPLATE = "Build.xml.tmpl";
69+
static private final String ANT_BUILD_TEMPLATE = "Build.xml.tmpl";
70+
71+
// Gradle files
72+
static private final String TOP_GRADLE_BUILD_TEMPLATE = "TopBuild.gradle.tmpl";
73+
static private final String GRADLE_SETTINGS_TEMPLATE = "Settings.gradle.tmpl";
74+
static private final String FRAGMENT_GRADLE_BUILD_TEMPLATE = "FragmentBuild.gradle.tmpl";
7075

7176
// TODO: ask base package name when exporting signed apk
7277
// static final String basePackage = "changethispackage.beforesubmitting.tothemarket";
@@ -1044,7 +1049,7 @@ private void writeAntProps(final File file) {
10441049

10451050

10461051
private void writeBuildXML(final File xmlFile, final String projectName) {
1047-
File xmlTemplate = mode.getContentFile("templates/" + BUILD_TEMPLATE);
1052+
File xmlTemplate = mode.getContentFile("templates/" + ANT_BUILD_TEMPLATE);
10481053

10491054
HashMap<String, String> replaceMap = new HashMap<String, String>();
10501055
replaceMap.put("@@project_name@@", projectName);
@@ -1080,6 +1085,7 @@ private void writeLocalProps(final File file) {
10801085
writer.close();
10811086
}
10821087

1088+
10831089
static final String ICON_192 = "icon-192.png";
10841090
static final String ICON_144 = "icon-144.png";
10851091
static final String ICON_96 = "icon-96.png";
@@ -1364,7 +1370,6 @@ private void writeWatchFaceCanvasService(final File srcDirectory, String[] permi
13641370

13651371

13661372
private void writeCardboardActivity(final File srcDirectory, String[] permissions) {
1367-
13681373
File javaTemplate = mode.getContentFile("templates/" + CARDBOARD_ACTIVITY_TEMPLATE);
13691374
File javaFile = new File(new File(srcDirectory, getPackageName().replace(".", "/")), "MainActivity.java");
13701375

@@ -1511,230 +1516,58 @@ public void cleanup() {
15111516
}
15121517

15131518

1514-
protected void createGradleProject(File projectFolder, File exportFolder) {
1519+
protected void createGradleProject(File projectFolder, File exportFolder) throws IOException, SketchException {
1520+
// Upacking gradlew
1521+
File gradlewFile = mode.getContentFile("mode/gradlew.zip");
1522+
AndroidMode.extractFolder(gradlewFile, exportFolder, true, true);
15151523

1524+
1525+
// Top level gradle files
1526+
File buildTemplate = mode.getContentFile("templates/" + TOP_GRADLE_BUILD_TEMPLATE);
1527+
File buildlFile = new File(exportFolder, "build.gradle");
1528+
Util.copyFile(buildTemplate, buildlFile);
1529+
1530+
writeLocalProps(new File(exportFolder, "local.properties"));
1531+
writeFile(new File(exportFolder, "gradle.properties"), new String[]{"org.gradle.jvmargs=-Xmx1536m"});
1532+
1533+
File settingsTemplate = mode.getContentFile("templates/" + GRADLE_SETTINGS_TEMPLATE);
1534+
File settingsFile = new File(exportFolder, "settings.gradle");
1535+
HashMap<String, String> replaceMap = new HashMap<String, String>();
1536+
replaceMap.put("@@project_modules@@", "':app'");
1537+
AndroidMode.createFileFromTemplate(settingsTemplate, settingsFile, replaceMap);
1538+
1539+
// Creating app module
1540+
File appFolder = mkdirs(exportFolder, "app");
1541+
1542+
File appBuildTemplate = mode.getContentFile("templates/" + FRAGMENT_GRADLE_BUILD_TEMPLATE);
1543+
File appBuildFile = new File(appFolder, "build.gradle");
1544+
replaceMap = new HashMap<String, String>();
1545+
replaceMap.put("@@package_name@@", getPackageName());
1546+
replaceMap.put("@@min_sdk@@", AndroidBuild.min_sdk_fragment);
1547+
replaceMap.put("@@target_sdk@@", AndroidBuild.target_sdk);
1548+
replaceMap.put("@@version_code@@", manifest.getVersionCode());
1549+
replaceMap.put("@@version_name@@", manifest.getVersionName());
1550+
AndroidMode.createFileFromTemplate(appBuildTemplate, appBuildFile, replaceMap);
1551+
1552+
writeFile(new File(appFolder, "proguard-rules.pro"), new String[]{"# Add project specific ProGuard rules here."});
1553+
1554+
File coreFile = new File(projectFolder, "libs/processing-core.jar");
1555+
File libsFolder = mkdirs(appFolder, "libs");
1556+
Util.copyFile(coreFile, new File(libsFolder, "processing-core.jar"));
1557+
1558+
File mainFolder = mkdirs(appFolder, "src/main");
1559+
File javaFolder = mkdirs(mainFolder, "java");
1560+
File resFolder = mkdirs(mainFolder, "res");
1561+
1562+
Util.copyFile(new File(projectFolder, "AndroidManifest.xml"), new File(mainFolder, "AndroidManifest.xml"));
1563+
Util.copyDir(new File(projectFolder, "res"), resFolder);
1564+
Util.copyDir(new File(projectFolder, "src"), javaFolder);
15161565
}
15171566

1518-
1519-
// Some leftovers from earlier versions of the mode, probably should remove at some point...
1520-
/*
1521-
// SDK tools 17 have a problem where 'dex' won't pick up the libs folder
1522-
// (which contains our friend processing-core.jar) unless your current
1523-
// working directory is the same as the build file. So this is an unpleasant
1524-
// workaround, at least until things are fixed or we hear of a better way.
1525-
// This was fixed in SDK 19 (and Processing revision 0205) so we've now
1526-
// disabled this portion of the code.
1527-
protected boolean antBuild_dexworkaround() throws SketchException {
1528-
try {
1529-
// ProcessHelper helper = new ProcessHelper(tmpFolder, new String[] { "ant", target });
1530-
// Windows doesn't include full paths, so make 'em happen.
1531-
String cp = System.getProperty("java.class.path");
1532-
String[] cpp = PApplet.split(cp, File.pathSeparatorChar);
1533-
for (int i = 0; i < cpp.length; i++) {
1534-
cpp[i] = new File(cpp[i]).getAbsolutePath();
1535-
}
1536-
cp = PApplet.join(cpp, File.pathSeparator);
1537-
1538-
// Since Ant may or may not be installed, call it from the .jar file,
1539-
// though hopefully 'java' is in the classpath.. Given what we do in
1540-
// processing.mode.java.runner (and it that it works), should be ok.
1541-
String[] cmd = new String[] {
1542-
"java",
1543-
"-cp", cp, //System.getProperty("java.class.path"),
1544-
"org.apache.tools.ant.Main", target
1545-
// "ant", target
1546-
};
1547-
ProcessHelper helper = new ProcessHelper(tmpFolder, cmd);
1548-
ProcessResult pr = helper.execute();
1549-
if (pr.getResult() != 0) {
1550-
// System.err.println("mo builds, mo problems");
1551-
System.err.println(pr.getStderr());
1552-
System.out.println(pr.getStdout());
1553-
// the actual javac errors and whatnot go to stdout
1554-
antBuildProblems(pr.getStdout(), pr.getStderr());
1555-
return false;
1556-
}
1557-
1558-
} catch (InterruptedException e) {
1559-
return false;
1560-
1561-
} catch (IOException e) {
1562-
e.printStackTrace();
1563-
return false;
1564-
}
1565-
return true;
1566-
}
1567-
1568-
public class HopefullyTemporaryWorkaround extends org.apache.tools.ant.Main {
1569-
1570-
protected void exit(int exitCode) {
1571-
// I want to exit, but let's not System.exit()
1572-
System.out.println("gonna exit");
1573-
System.out.flush();
1574-
System.err.flush();
1575-
}
1576-
}
1577-
1578-
1579-
protected boolean antBuild() throws SketchException {
1580-
String[] cmd = new String[] {
1581-
"-main", "processing.mode.android.HopefullyTemporaryWorkaround",
1582-
"-Duser.dir=" + tmpFolder.getAbsolutePath(),
1583-
"-logfile", "/Users/fry/Desktop/ant-log.txt",
1584-
"-verbose",
1585-
"-help",
1586-
// "debug"
1587-
};
1588-
HopefullyTemporaryWorkaround.main(cmd);
1589-
return true;
1590-
// ProcessResult listResult =
1591-
// new ProcessHelper("ant", "debug", tmpFolder).execute();
1592-
// if (listResult.succeeded()) {
1593-
// boolean badness = false;
1594-
// for (String line : listResult) {
1595-
// }
1596-
// }
1597-
}
1598-
1599-
private void copyLibraries(final File libsFolder,
1600-
final File assetsFolder) throws IOException {
1601-
// Copy any libraries to the 'libs' folder
1602-
for (Library library : getImportedLibraries()) {
1603-
File libraryFolder = new File(library.getPath());
1604-
// in the list is a File object that points the
1605-
// library sketch's "library" folder
1606-
final File exportSettings = new File(libraryFolder, "export.txt");
1607-
final HashMap<String, String> exportTable =
1608-
Base.readSettings(exportSettings);
1609-
final String androidList = exportTable.get("android");
1610-
String exportList[] = null;
1611-
if (androidList != null) {
1612-
exportList = PApplet.splitTokens(androidList, ", ");
1613-
} else {
1614-
exportList = libraryFolder.list();
1615-
}
1616-
for (int i = 0; i < exportList.length; i++) {
1617-
exportList[i] = PApplet.trim(exportList[i]);
1618-
if (exportList[i].equals("") || exportList[i].equals(".")
1619-
|| exportList[i].equals("..")) {
1620-
continue;
1621-
}
1622-
1623-
final File exportFile = new File(libraryFolder, exportList[i]);
1624-
if (!exportFile.exists()) {
1625-
System.err.println("File " + exportList[i] + " does not exist");
1626-
} else if (exportFile.isDirectory()) {
1627-
System.err.println("Ignoring sub-folder \"" + exportList[i] + "\"");
1628-
} else {
1629-
final String name = exportFile.getName();
1630-
final String lcname = name.toLowerCase();
1631-
if (lcname.endsWith(".zip") || lcname.endsWith(".jar")) {
1632-
// As of r4 of the Android SDK, it looks like .zip files
1633-
// are ignored in the libs folder, so rename to .jar
1634-
final String jarName =
1635-
name.substring(0, name.length() - 4) + ".jar";
1636-
Base.copyFile(exportFile, new File(libsFolder, jarName));
1637-
} else {
1638-
// just copy other files over directly
1639-
Base.copyFile(exportFile, new File(assetsFolder, name));
1640-
}
1641-
}
1642-
}
1643-
}
1644-
}
1645-
1646-
private void writeResLayoutMainFragment(final File file) {
1647-
final PrintWriter writer = PApplet.createWriter(file);
1648-
writer.println("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
1649-
writer.println("<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"");
1650-
writer.println(" android:orientation=\"vertical\"");
1651-
writer.println(" android:layout_width=\"fill_parent\"");
1652-
writer.println(" android:layout_height=\"fill_parent\">");
1653-
writer.println("</LinearLayout>");
1654-
}
1655-
1656-
1657-
// This recommended to be a string resource so that it can be localized.
1658-
// nah.. we're gonna be messing with it in the GUI anyway...
1659-
// people can edit themselves if they need to
1660-
private static void writeResValuesStrings(final File file,
1661-
final String className) {
1567+
private void writeFile(final File file, String[] lines) {
16621568
final PrintWriter writer = PApplet.createWriter(file);
1663-
writer.println("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
1664-
writer.println("<resources>");
1665-
writer.println(" <string name=\"app_name\">" + className + "</string>");
1666-
writer.println("</resources>");
1569+
for (String line: lines) writer.println(line);
16671570
writer.flush();
16681571
writer.close();
1669-
}
1670-
1671-
private void copySupportV4(File libsFolder) throws SketchException {
1672-
File sdkLocation = sdk.getSdkFolder();
1673-
File supportV4Jar = new File(sdkLocation, "extras/android/support/v4/android-support-v4.jar");
1674-
if (!supportV4Jar.exists()) {
1675-
SketchException sketchException =
1676-
new SketchException("Please install support repository from SDK manager");
1677-
throw sketchException;
1678-
} else {
1679-
try {
1680-
Base.copyFile(supportV4Jar, new File(libsFolder, "android-support-v4.jar"));
1681-
} catch (IOException e) {
1682-
e.printStackTrace();
1683-
}
1684-
}
1685-
}
1686-
1687-
private boolean verifySignedPackage(File signedPackage) throws Exception {
1688-
String[] args = {
1689-
"-verify", signedPackage.getCanonicalPath()
1690-
};
1691-
1692-
PrintStream defaultPrintStream = System.out;
1693-
1694-
ByteArrayOutputStream baos = new ByteArrayOutputStream();
1695-
PrintStream printStream = new PrintStream(baos);
1696-
System.setOut(printStream);
1697-
1698-
SystemExitControl.forbidSystemExitCall();
1699-
try {
1700-
JarSigner.main(args);
1701-
} catch (SystemExitControl.ExitTrappedException ignored) { }
1702-
SystemExitControl.enableSystemExitCall();
1703-
1704-
System.setOut(defaultPrintStream);
1705-
String result = baos.toString();
1706-
1707-
baos.close();
1708-
printStream.close();
1709-
1710-
return result.contains("verified");
1711-
}
1712-
*/
1713-
}
1714-
1715-
/*
1716-
// How to prevent the System.exit() call, could be useful...
1717-
// http://www.avanderw.co.za/preventing-calls-to-system-exit-in-java/
1718-
class SystemExitControl {
1719-
1720-
@SuppressWarnings("serial")
1721-
public static class ExitTrappedException extends SecurityException {
1722-
}
1723-
1724-
public static void forbidSystemExitCall() {
1725-
final SecurityManager securityManager = new SecurityManager() {
1726-
@Override
1727-
public void checkPermission(Permission permission) {
1728-
if (permission.getName().contains("exitVM")) {
1729-
throw new ExitTrappedException();
1730-
}
1731-
}
1732-
};
1733-
System.setSecurityManager(securityManager);
1734-
}
1735-
1736-
public static void enableSystemExitCall() {
1737-
System.setSecurityManager(null);
1738-
}
1572+
}
17391573
}
1740-
*/

src/processing/mode/android/AndroidMode.java

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -404,7 +404,13 @@ public static void createFileFromTemplate(final File tmplFile, final File destFi
404404
pw.close();
405405
}
406406

407-
public static void extractFolder(File file, File newPath, boolean setExec) throws IOException {
407+
public static void extractFolder(File file, File newPath,
408+
boolean setExec) throws IOException {
409+
extractFolder(file, newPath, setExec, false);
410+
}
411+
412+
public static void extractFolder(File file, File newPath,
413+
boolean setExec, boolean remRoot) throws IOException {
408414
int BUFFER = 2048;
409415
ZipFile zip = new ZipFile(file);
410416
Enumeration<? extends ZipEntry> zipFileEntries = zip.entries();
@@ -414,6 +420,13 @@ public static void extractFolder(File file, File newPath, boolean setExec) throw
414420
// grab a zip file entry
415421
ZipEntry entry = zipFileEntries.nextElement();
416422
String currentEntry = entry.getName();
423+
424+
if (remRoot) {
425+
// Remove root folder from path
426+
int idx = currentEntry.indexOf(File.separator);
427+
currentEntry = currentEntry.substring(idx + 1);
428+
}
429+
417430
File destFile = new File(newPath, currentEntry);
418431
//destFile = new File(newPath, destFile.getName());
419432
File destinationParent = destFile.getParentFile();
@@ -423,7 +436,7 @@ public static void extractFolder(File file, File newPath, boolean setExec) throw
423436

424437
String ext = PApplet.getExtension(currentEntry);
425438
if (setExec && ext.equals("unknown")) {
426-
// On some OS X machines the android binaries loose their executable
439+
// On some OS X machines the android binaries lose their executable
427440
// attribute, rendering the mode unusable
428441
destFile.setExecutable(true);
429442
}

templates/FragmentBuild.gradle.tmpl

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
apply plugin: 'com.android.application'
2+
3+
android {
4+
compileSdkVersion @@target_sdk@@
5+
buildToolsVersion "24.0.1"
6+
defaultConfig {
7+
applicationId "@@package_name@@"
8+
minSdkVersion @@min_sdk@@
9+
targetSdkVersion @@target_sdk@@
10+
versionCode @@version_code@@
11+
versionName "@@version_name@@"
12+
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
13+
}
14+
buildTypes {
15+
release {
16+
minifyEnabled false
17+
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
18+
}
19+
}
20+
}
21+
22+
dependencies {
23+
compile fileTree(include: ['*.jar'], dir: 'libs')
24+
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
25+
exclude group: 'com.android.support', module: 'support-annotations'
26+
})
27+
compile 'com.android.support:appcompat-v7:23.4.0'
28+
compile 'com.android.support:design:23.4.0'
29+
testCompile 'junit:junit:4.12'
30+
compile files('libs/processing-core.jar')
31+
}

templates/Settings.gradle.tmpl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
include @@project_modules@@

0 commit comments

Comments
 (0)