Hi,
I have been working on getting Ceylon applications to run on Android, and while it's very early and rough, it's at a point where I can start accepting testers and contributions. I have been able to create a working APK written entirely in Ceylon, with Maven interop, using Gradle for building it.
How can you test this?
===
Checkout the `android` branch of the Ceylon distribution (
https://github.com/ceylon/ceylon) and build your distribution with `ant clean dist`. It's a bit behind `master`, but not by much. Warning: this branch will be forcibly rewritten as its commit history is crap and temporary. It's also only been tested for Android and it will likely just break if you try to use it outside of Android building. Naturally all that will be fixed in due time. This is bleeding edge, remember?
You will need to edit the `com.redhat.ceylon.gradle.android.MyCeylonCompileTask` class to change `/home/stephane/src/java-eclipse/ceylon/dist/dist/bin/ceylon`to point to your distribution (of course it will be configurable later).
Because it has a `sample-app` that depends on the Gradle plugin being built, you will need to comment out the `include 'sample-app'`line in `settings.gradle` until you've built the plugin first with:
`$ ANDROID_HOME=.../Android/Sdk/ ./gradlew :android:build`
Now you can uncomment that line back in `settings.gradle` and build your sample app with:
`$ ANDROID_HOME=.../Android/Sdk/ ./gradlew assembleDebug`
And stuff it onto your emulator with:
`$ .../Android/Sdk/tools/android avd &`
`$ .../Android/Sdk/platform-tools/adb install -r sample-app/build/outputs/apk/sample-app-debug.apk`
What I did so far
===
- added a `--jdk-provider` flag to the compiler which takes a module that contains the Jdk, and treats it as the source for the Jdk you target. You point it to your android module and it will figure out which Jdk modules it contains from there, allowing you to resolve `java.base/7` from it instead of from the running Jdk.
- started fixing `import-jar` to deal with transitive dependencies, so we can import the android jar and whatever dependencies are declared in the Gradle build (which come from the Android Sdk Maven repo)
- hacked `jigsaw create-mlib` to generate a `ceylon.metamodel` file which describes the metamodel statically, so that at run-time the metamodel gets initialised with this. This will move to a more appropriate command
- got the Gradle plugin to:
a/ import the Maven (aar file types mostly, which the Android Gradle plugin unpacks for us) modules into a Ceylon repo
b/ compile our Ceylon module with that repo configured, and the generated source paths (containing `R.java`) configured too
c/ generate a list of jars required by our Ceylon modules (as in, the Ceylon runtime) and static metamodel file
d/ pass on that list (minus those already found by Gradle) to the Android Gradle build so it can dex them and include them in the Apk
What remains to be done
===
- clean up and polish
- support variants and flavours in the Gradle plugin
- properly set up input/output and incremental build in the Gradle plugin
- make the Gradle plugin configurable
- very likely make the Gradle plugin use the Gradle Ceylon plugin Renato wrote, not sure how
- deal with `java.lang::CharSequence` because Android seems to use this a lot
- add `--exclude` to `jigsaw create-mlib`
- trim module dependencies in dist to reduce runtime footprint
What feedback/help you can give
===
If you know Gradle, please help improve my plugin, it's currently working but not well written at all, and not complete or configurable.
If you know Android: try out the same app, try adding more Android typical features to it, see where we need to improve support for both Ceylon and the Gradle plugin.