Saturday, February 4, 2012

Ant Build, Install and LAUNCH

After using Eclipse, like all new android developers, for quite some time I got very used to the process of clicking GO and having Eclipse compile, package, install and then launch my android app. The latest ADT build did screw up the build output though, so if you had it set to verbose it would crash while trying to build. I enjoy having a verbose build, I like seeing all the steps.

Well, after my latest OS Re-Install I decided to give IntelliJ IDEA a go. I liked eclipse, but I must say that IntelliJ's Perforce integration is much better, and I like they way it separates different projects. I'm still getting used to it, but I quite like it. However, often times I would try to launch my app and IntelliJ would compile, package and then just sit there. There was a background task running that had a full progress bar and output of "Packaging Android Resources" or something like that. IntelliJ also has no verbose build output for android compiling, which is quite frustrating.

I've been wanting to learn more with Ant anyway, so I decided to just start building with the command line. Here's a piece of advice if you're using Intellij and going to build with Ant... do NOT use the "Generate And Build... option. The file it generates does will compile everything fine, but it won't package it into your apk for you. Not sure it converted your classes to dex either. So, to get your build.xml file for Ant, use the command:

android update project -p <path to project>


This will create your build.xml file as well as multiple properties files. local.properties contains properties to JDK and the Android SDK, and you can put anything else that is specific to your machine here. ant.properties contains any properties you want to adjust for the project and can be added to a SCM system without worrying about local machine settings. The last file, project.properties, is generated from reading your AndroidManifest.xml file, and will be re-generated, so don't modify it!

This was working well except for one thing... The "ant debug install" command would build my project, package my apk with my debug key and install it to my device. It would not however launch my Launcher activity. So in my build.xml file I added a custom target, launch, which depends on install, to scan the xml file for the package and name of the LAUNCHER activity and start it using adb. Here is the target code:

<!-- my custom launch target -->
    <target name="launch" depends="install">
       
     <if> <condition><not><isset property="manifest.package"/></not></condition>
     <then>
          <xpath input="AndroidManifest.xml"
                expression="/manifest/@package" output="manifest.package" />
        </then>
        </if>
        
        <if>
     <condition>
      <not><isset property="launcher.activity"/></not>
     </condition>
     <then>
         <echo>launcher.activity not set, attempting to scan manifest file for LAUNCHER Activity</echo>
          <xpath input="AndroidManifest.xml" 
          expression="/manifest/application/activity[intent-filter[category/@android:name='android.intent.category.LAUNCHER']]/@android:name"
          output="launcher.activity" default="__NONE__" />
     </then>
     </if>
     <if> <condition><not><equals arg1="${launcher.activity}" arg2="__NONE__" /></not></condition>
      <then>
        <echo>Launching Activity ${manifest.package}/${launcher.activity}</echo>
        <echo>adb ${adb.device.arg} shell am start ${manifest.package}/${launcher.activity}</echo>
        <exec executable="${adb}" failonerror="false">
          <arg line="${adb.device.arg}"/>
          <arg value="shell" />
          <arg value="am" />
          <arg value="start" />
          <arg value="${manifest.package}/${launcher.activity}" />
         </exec>
      </then>
      <else>
         <echo>Could not find an Activity defined in AndroidManifest.xml containing LAUNCHER category.</echo>     
      </else>
      </if>
    </target>

The target will use the launcher.activity property that you can set in ant.properties if you want, or it will try to scan the AndroidManifest.xml file to find the first activity that has <category android:name="android.intent.category.LAUNCHER" /> in it's intent filter. It will also use the default device, which you can change with the "-Dadb.device.arg=" option on the ant command line. I am much happier with my ant build command now!

No comments:

Post a Comment