Tuesday, July 26, 2011
Dropbox and Git bare repository
Monday, July 25, 2011
Adding Scala libraries to the Android emulator
After a short search we stumbled on a really interesting article about preloading the Scala libraries to the Android emulator. All we needed to do was predex our Scala library and create a custom ramdisk with some extra rules in the init.rc file for loading the Scala libraries during the emulator startup. Jan Berkel also had a really good tutorial about how to preinstall the Scala libaries to the emulator (and also to a rooted phone). With these resources at hand I first cloned the scripts provided by Berkel from the Github (derived from Stéphane Micheloud's scripts).
git clone git://github.com/jberkel/android-sdk-scala.git
I needed to set SCALA_HOME and ANDROID_SDK_ROOT, to get the scripts to run correctly.
set SCALA_HOME=PATH_TO_SCALA
set ANDROID_SDK_ROOT=PATH_TO_ANDROID_SDK
I also had to manually modify the createdexlib.bat, since Google had changed the location of the dx compiler.
Then I configured the Scala 2.9.0 version into my SCALA_HOME variable and ran the scipts. I also downloaded the custom ramdisk.img (avd.v10 [2.3.3]) from Micheloud's article. I tried to get the emulator to start with the new custom image by giving it as a parameter in the emulator start-up, but without success. So I had to replace the original ramdisk.img with my custom one.
The original image is located in the ANDROID_SDK_ROOT
Then I started the Android emulator and ran the following commands in the
adb.exe shell ls / (you should run this command until you get a proper list of files)
adb.exe shell mkdir -p /data/framework
adb.exe push PATH_TO_ANDROID_SDK_SCALA
adb.exe push
adb.exe push
adb.exe push
adb.exe push
with Proguard | without Proguard (Scala:Provided) | without Proguard and with lazyunpackage | without Proguard with scala cc (fcs:false) and lazyunpack | |
mvn clean package | 1 min 56 sec | 35 sec | 27 sec | 21 sec |
mvn package | 1 min 32 sec | 25 sec | 24 sec | 14 sec |
Monday, July 11, 2011
Improve your maven android build speed
Here’s a nice way of shaving around 10 seconds off your average maven builds total time when building Scala Android applications.
You know the part when you need to unpack everything to have ProGuard go through all your classes to remove that extra fat. Well, even if you make a lot of changes to your code, most of the time is spent unpacking the libraries (Scala and Android mainly). And these libraries don’t change that often. So after you’ve done it once, and they have already been unpacked to your target directory, why do it again? Well, someone figured that out and now it’s added to maven-android-plugin in version 2.9.0-beta-5, so switch to that from 2.8.4 which is what you are probably using.
Then all you need to do is add the line:
<lazyLibraryUnpack>true</lazyLibraryUnpack>
under the <configuration> of your maven-android-plugin.
If this causes force closes on your device/emulator, check that your ProGuard settings are not too aggressive.
Wednesday, July 6, 2011
Andengine application with Scala
Folders
Folder paths are only for example and you can change them from the pom.xml.
/src/main/resources/ - all none code stuff
/src/main/resources/assets/ - folder that contains all loadable content
/src/main/scala - all code
/src/main/android -all android specific stuff (configured in the pom.xml)
You can get the Android specific content to the /src/main/android folder by creating an empty Android module with IntelliJ Idea. Then copy AndroidManifest.xml and the res folder from the generated module to the /src/main/android folder in your Maven project.
Android config
Set the executable applications package as well as the executable file name in AndroidManifest.xml
/src/main/android/AndroidManifest.xml
Give a proper name to your application
/src/main/android/res/values/strings.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">ParticleSystemSimple</string>
</resources>
Code
This is the good stuff, finally!
First create a proper package by right clicking the /src/main/scala folder
Next, create the Scala class. Right click the newly created package and select new -> Scala Class
package com.studfarm.example
import com.studfarm.example.ParticleSystemSimpleExample._
ParticleSystemSimpleExample {}
Create a companion object for the class. Companion objects are used to store all static methods and variables. An object is called a companion object when the object is in the same file with the class and has the same name as the class.
Add these to the companion object:
val CAMERA_WIDTH:Int = 720
val CAMERA_HEIGHT:Int = 480
Remember to import the companion object so you can use the static methods and variables more easily.
package com.studfarm.example
import com.studfarm.example.ParticleSystemSimpleExample._
class ParticleSystemSimpleExample {
}
object ParticleSystemSimpleExample {
val CAMERA_WIDTH:Int = 720
val CAMERA_HEIGHT:Int = 480
}
Next we need to inherit the BaseGameActivity. Add extends BaseGameActivity to your class and accept the import. Implement the following methods:
- onLoadEngine:Engine
- onLoadResources
- onLoadScene:Scene
- onLoadComplete
Unfortunately the result is not clean and you'll need to add an override keyword in front of every def generated.
package com.studfarm.example
import org.anddev.andengine.ui.activity.BaseGameActivity
class ParticleSystemSimpleExample extends BaseGameActivity{
override def onLoadScene() = null
override def onLoadResources() {}
override def onLoadEngine() = null
override def onLoadComplete() {}
}
object ParticleSystemSimpleExample {
}
Next we'll implement the methods.OnLoadEngine
When the program is loaded, show a text to the user and set the camera.
override def onLoadEngine:Engine= {
Toast.makeText(this, "Touch the screen to move the particlesystem.", Toast.LENGTH_LONG).show
this.mCamera = new Camera(0, 0, CAMERA_WIDTH, CAMERA_HEIGHT)
return new Engine(new EngineOptions(true, ScreenOrientation.LANDSCAPE, new RatioResolutionPolicy(CAMERA_WIDTH, CAMERA_HEIGHT), this.mCamera));
}
onLoadResourcesLoads all resources for the application/game
override def onLoadResources {
this.mTexture = new Texture(32, 32, TextureOptions.BILINEAR_PREMULTIPLYALPHA);
this.mParticleTextureRegion = TextureRegionFactory.createFromAsset(this.mTexture, this, "gfx/particle_point.png", 0, 0);
this.mEngine.getTextureManager().loadTexture(this.mTexture);
}
particle_point.png is placed under /src/main/resources/assets/gfx/ folderCreate the Scene:
override def onLoadScene:Scene= {
this.mEngine.registerUpdateHandler(new FPSLogger());
val scene = new Scene(1);
val particleEmitter = new CircleOutlineParticleEmitter(CAMERA_WIDTH * 0.5f, CAMERA_HEIGHT * 0.5f + 20, 80);
val particleSystem = new ParticleSystem(particleEmitter, 60, 60, 360, this.mParticleTextureRegion);
scene.setOnSceneTouchListener(new IOnSceneTouchListener() {
override def onSceneTouchEvent(pScene:Scene, pSceneTouchEvent:TouchEvent):Boolean= {
particleEmitter.setCenter(pSceneTouchEvent.getX(), pSceneTouchEvent.getY());
true;
}
particleSystem.addParticleInitializer(new ColorInitializer(1, 0, 0))
particleSystem.addParticleInitializer(new AlphaInitializer(0))
particleSystem.setBlendFunction(GL10.GL_SRC_ALPHA, GL10.GL_ONE)
particleSystem.addParticleInitializer(new VelocityInitializer(-2, 2, -20, -10))
particleSystem.addParticleInitializer(new RotationInitializer(0.0f, 360.0f))
particleSystem.addParticleModifier(new ScaleModifier(1.0f, 2.0f, 0, 5))
particleSystem.addParticleModifier(new ColorModifier(1, 1, 0, 0.5f, 0, 0, 0, 3))
particleSystem.addParticleModifier(new ColorModifier(1, 1, 0.5f, 1, 0, 1, 4, 6))
particleSystem.addParticleModifier(new AlphaModifier(0, 1, 0, 1))
particleSystem.addParticleModifier(new AlphaModifier(1, 0, 5, 6))
particleSystem.addParticleModifier(new ExpireModifier(6, 6))
scene.getLastChild().attachChild(particleSystem)
});
return scene;
}
All done. Run the mvn clean package. You should now have a working application. You can test it with the Android emulator or with a real Android phone.Quickly converting AndEngine examples to Scala
After you have created a base project for yourself with all the necessities (Scala, Android and AndEngine), you can first:
- import one of the AndEngine examples (written in java) to your project,
- select the contents of the file,
- create a new Scala class and
- paste the contents you copied earlier to that file.
Well damn right I do! The end result sure isn’t the beautiful functional programming you want to achieve, and it does need some minor adjusting but it sure is a fast way to kick start your AndEngine experience with Scala.
Sunday, July 3, 2011
Your first scala-android apk
To get your environment running, please check this post by Janne.
Ok, let's get to the interesting part. Combining Scala, Maven and Android SDK with a working development environment.
Properties
<properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>5</maven.compiler.source> <maven.compiler.target>5</maven.compiler.target> </properties>
New dependencies
- Android
- Andengine (2d engine)
<dependencies> <dependency> <groupId>com.google.android</groupId> <artifactId>android</artifactId> <version>2.3.3</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.andengine</groupId> <artifactId>andengine</artifactId> <version>1.0</version> </dependency> </dependencies>
Since the Andengine package is not included in any Maven repository, you'll need to add the file by hand:
You can download the Andengine file here.
Remember to set packaging to apk!
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId> <artifactId>first-application</artifactId> <version>1.0</version> <packaging>apk</packaging> <name>first-application</name>
Plugins
The Android plugin that handles the apk generation.
<plugin>
<groupId>com.jayway.maven.plugins.android.generation2</groupId> <artifactId>maven-android-plugin</artifactId> <version>2.8.4</version> <configuration> <sdk> <!-- Don't forget to set your ANDROID_HOME environment variable to your SDK directory! --> <path>${env.ANDROID_HOME}</path> <!-- Platform 10 is Android 2.3.3 --> <platform>10</platform> </sdk> <jvmArguments> <jvmArgument>-Xmx1024m</jvmArgument> </jvmArguments> <!-- All of these go into the /src/main/android/ directory, we don't want to polute the project root directory. --> <androidManifestFile>${project.basedir}/src/main/android/AndroidManifest.xml</androidManifestFile> <resourceDirectory>${project.basedir}/src/main/android/res</resourceDirectory> <assetsDirectory>${project.basedir}/src/main/android/assets</assetsDirectory> <nativeLibrariesDirectory>${project.basedir}/src/main/android/native</nativeLibrariesDirectory> <resourceOverlayDirectory>${project.basedir}/src/main/android/overlay</resourceOverlayDirectory> <deleteConflictingFiles>true</deleteConflictingFiles> <undeployBeforeDeploy>true</undeployBeforeDeploy> </configuration> <extensions>true</extensions> </plugin>
Last we need the most important plugin of them all, ProGuard. Without this plugin the apk generation will fail since the Scala dependency will generate too many files.
<plugin><groupId>com.pyx4me</groupId> <artifactId>proguard-maven-plugin</artifactId> <version>2.0.4</version> <executions> <execution> <phase>process-classes</phase> <goals> <goal>proguard</goal> </goals> </execution> </executions> <configuration> <injar>android-classes</injar> <libs> <lib>${java.home}/lib/rt.jar</lib> </libs> <obfuscate>false</obfuscate> <options> <option>-keep public class * extends android.app.Activity</option> <option>-keep public class * extends android.app.Application</option> <option>-keep public class * extends android.app.Service</option> <option>-keep public class * extends android.content.BroadcastReceiver</option> <option>-keep public class * extends android.content.ContentProvider</option> <option>-dontskipnonpubliclibraryclasses</option> <option>-dontoptimize</option> <option>-printmapping map.txt</option> <option>-printseeds seed.txt</option> <option>-ignorewarnings</option> </options> </configuration> </plugin>With these settings you should be able to create a working development environment for Android development with Scala. Make a test run by running the following command: mvn package to see if the environment compiles.
Congrats! You have an Android application that does nothing.
Also, if you can't get things working with the tutorial, here's the pom.xml you can use to get your application to compile.
From my point of view getting Android, Scala and Maven working together is a real pain in the ass and I couldn't have done the configuration without the following tutorials:
http://www.scala-lang.org/node/345 (Scala with Maven) Thanks to the Scala community.
Building Android applications with Maven and IntelliJ 11/26/2010 Thanks to Christian Bauer for an exellent tutorial.
Also some more information from Proguard:
http://code.google.com/p/maven-android-plugin/wiki/ProGuard?spec=svn331
Saturday, July 2, 2011
Enable fast Scala compiler (fsc) on IntelliJ IDEA
Regular compilation with Scala compiler is really slow. Most of the time is spent compiling parts of Scala libraries, instead of your own code though. Solution is to use fsc (fast scala compiler), which is daemon that compiles the required Scala libraries on the first compilation, and stays in memory after that, so your subsequent compilations after a lot faster.
My first guess was to just click the checkbox “Use fsc” in the Scala plugin settings page. This alone only causes exceptions. You also need to create a Scala compilation server instance for yourself.
- Open the 'Edit (Run/Debug) Configurations' dialog
- Click on the [+] in left top corner of the window
- Select 'Scala Compilation Server' (should be near the end of the list)
- Give the new launcher a name (e.g. 'my fsc server') and hit OK
- Press the Play icon to compile and run as usual.
Your second press of Play should be a lot faster!