David Janes' Code Weblog

November 20, 2009

How to use XCode for Android Projects

android,code fragments,ideas,macintosh · David Janes · 6:07 pm ·

Let’s assume you already have an Android project on your Mac.

Create the XCode Project

  • start XCode
  • select File > New Project…
  • select External Build System
  • go to the parent directory of your Android Project
  • in the Save As: field, enter the directory name of your Android Project
  • select the scarily-misnamed Replace option [not in XCode 4 -- thanks Jusin]

Add Files

In your new XCode project:

  • select first item in the left hand column, which is the name of your project
  • right-click, select Add > Existing Files…
  • select add files (don’t select the Copy option)
  • organize as desired (I like to do a lot of grouping). You should be probably adding at least your Java files and your Layout resources.

Configure your Build Target

In your new XCode project:

  • look for Targets
  • inside will be a target for your project’s name
  • double click on it
    • change Build Tool to ant
    • change Arguments to install

Clicking ⌘B should now compile your project.

Note: if you figure out how to have a Build vs. Build & Install (e.g. ⌘ENTER) please let me know!.

Getting XCode to Recognize Java errors

  • Reconfigure the Build Target, changing ant to ./xant
  • Make a file xant in the project’s home directory, using the code below
  • do (from a Terminal) chmod a+x xant
#!/usr/bin/env python

import sys
import re
import subprocess

av = list(sys.argv)
av[0] = "ant"

p = subprocess.Popen(av, stdout = subprocess.PIPE)

javac_rex = re.compile(" +[[]javac[]] +")
line_rex = re.compile("[.]java:[\d]+:")

pending = ""
while True:
    d = p.stdout.read(128)
    if not d:
        break

    d = pending + d

    nx = d.rfind('\n')
    if nx == -1:
        pending = d
        continue
    else:
        d, pending = d[:nx + 1], d[nx + 1:]

        d = javac_rex.sub("", d)
        d = line_rex.sub(r"\g error: ", d)
        sys.stdout.write(d)
        sys.stdout.flush()

sys.stdout.write(pending)
p.wait()
sys.exit(p.returncode)

Note: this code has been updated from the original post. It now reads little chunks and outputs them immediately rather than post-processing the ant output.

26 comments

  1. David Oster · 2009-12-07 15:01

    RE: if you figure out how to have a Build vs. Build & Install (e.g. ⌘ENTER) please let me know!.

    If you edit your python script add these lines after:
    av = list(sys.argv)
    av[0] = “/usr/bin/ant”

    if len(av) == 1 :
    av.append(“compile”)

    then and leave Xcode’s build argument set to $ACTION, then you’ll find that get Xcode’s builds, installs, and clean connected through to ant.

  2. David Janes · 2009-12-08 18:48

    Oh god, awesome, thanks.

  3. David Oster · 2009-12-16 20:20

    After a further look, I’ve been using:
    #!/bin/bash
    if [ "x${ACTION}" == "xclean" ] ; then
    echo CLEAN
    # remove the generated files in bin (Assumes all files in bin are discardable.)
    cp /dev/null bin/a
    rm -rf bin/*
    else
    echo /usr/bin/ant -emacs ${ACTION} $(echo ${BUILD_STYLE} | tr ‘[A-Z]‘ ‘[a-z]‘)
    /usr/bin/ant -emacs ${ACTION} $(echo ${BUILD_STYLE} | tr ‘[A-Z]‘ ‘[a-z]‘)
    fi

    which handles Build, and Clean, for both the Debug and Release targets, but doesn’t do the install, and doesn’t have your Python error editing so Xcode will see it. You script does the install, which is more useful.

    Rather than following Apple’s directions and using an “External Build System” style target, an empty target with a series of custom build phases might work better. You could have a phase like this;

    #!/bin/bash
    if [ "false" == $(osascript -e 'tell application "Finder" to exists process "emulator"') ] ; then
    echo starting Emulator
    ../../android-sdk-mac/tools/emulator -avd ${MYAVD}
    else
    /usr/bin/ant install bin/${TARGET}
    fi

    to start the emulator, or if it was started, install the .apk on it. But that still doesn’t solve the problem of connecting Xcode’s Java debugger via TCP/IP to the environment in the emulator. Sorry I don’t have all the answers.

  4. David Oster · 2009-12-16 20:22

    But it does look like the -emacs command line option to ant makes the errors from ant immediately compatible with Xcode without any need to post process the error messages with Python.

  5. I’ve never worked with Android, but it might also be worth looking at Xcode’s Organizer feature. The Organizer lets you work with Ant/Java projects without cluttering them with Xcode project files. Apple’s doco on using the Organizer with Java is sparse, but these links are a start:
    http://developer.apple.com/mac/library/documentation/Java/Conceptual/Java14Development/02-JavaDevTools/JavaDevTools.html
    http://developer.apple.com/mac/library/documentation/DeveloperTools/Conceptual/XcodeProjectManagement/140-Using_the_Organizer/using_the_organizer.html

  6. David Janes · 2010-04-07 06:13

    Thank you Robert – I’ll check this out, as I’m just in the process of picking up this project again. Timely!

  7. [...] Between the two platforms, Xcode wins hands down as the more friendly dev environment for me. Others have even gone as far as configuring Xcode for Android development. [...]

  8. Alexidoia · 2010-10-22 09:38

    Unless I missunderstood, can we export an iphone app to blackburry with that method ?

  9. [...] How to use XCode for Android Projects ‹ Previous Post UITextField/UITextViewの文字入力で覚えておくと便利なこと [...]

  10. unfortunately, the “scarily misnamed Replace option” seems to be scarily correct in Xcode 4. I just used it and nuked a folder full of code. I had a copy, though, so no harm done here. you might want to alter your article.

  11. admin · 2011-07-25 05:41

    Thus updated! Thanks.

  12. @David, I’m having trouble with the last part of the xant file creation in terminal.

    I’m using chmod a+x xant but I get an error saying: “No such file or directory.”

    I’m in my project directory. Is there anything I’m doing wrong?

  13. admin · 2011-11-01 04:55

    What does “ls -l” and “pwd” show?

  14. diane · 2011-11-02 09:09

    hey everyone, i was hoping you could lend me a hand…
    i would like to create an ebook, with some swf animation, compatible with android.
    is Xcode compatible with android?
    and what open source (or not) program would you recommend for such a progect (given also my limited programing skills).

    thank you in advance for your help.
    Diane

  15. /Users/myuser/Applications/Eclipse/CIT252 — pwd

    drwxr-xr-x 14 myuser staff 476 Oct 31 21:25 CP Android

  16. Updated for XCode 4 and cleaned up a bit, see https://gist.github.com/1340255 — thanks for the great starting point, David!

  17. admin · 2011-11-04 15:37

    Bill: you’re not in the directory you created xant in.

  18. Austin · 2012-06-01 17:21

    When I try to build the project under ant, I’m getting an error that the build.xml file does not exist. I was wondering if I had to have the Android SDK anywhere specific for Xcode to pick up on those files.

    I’m using Xcode 4.3.2, and was wondering if anyone could lend a hand.

  19. admin · 2012-06-01 17:28

    Perhaps you didn’t make the xcode project in the same directory as where build.xml exists.

  20. Austin · 2012-06-13 20:39

    So the build.xml should be in the same place as the .xcodeproj? Where would I find the build.xml?

  21. Steve · 2012-07-12 10:06

    You guys are way better/smarter with this than I am…
    Can any of you PLEASE take Codea’s runtime and make Codea for Android???

    Codea: http://twolivesleft.com/Codea/
    Runtime: https://github.com/TwoLivesLeft/Codea-Runtime

    It is an AWESOME app for iPad, but I do NOT want to use iPad :)

  22. Felipe · 2012-11-07 06:21

    When i try to build i get Command ./xant failed with exit code 1 any tips?

  23. admin · 2012-11-07 07:36

    Try (individually)
    Make sure xant is executable.
    Change “./xant” to “ls” and see if you see xant.
    Also try “sh -x ./xant” instead

  24. Felipe · 2012-11-07 07:47

    Worked with Build Tool set to to ant, Arguments set to debug and then set Arguments to installd to send the .apk to a running AVD.

  25. Some comments for this post:
    - working well only ant/ debug install scheme.

    Other schemes don’t check changes inside files (using compiled files as well) and don’t show any compilation errors

    for scheme one i don’t see warning/errors line, bad thing.

    and bad thing – i can’t install into device and run apk…

    any suggestions?

  26. after some dancing, i was found solution:

    this is my version of ./xant (arguments- debug install):

    #!/bin/bash
    cp /dev/null bin/a

    echo /usr/bin/ant $1
    /usr/bin/ant $1

    adb install -r /Users/alex/Desktop/android-callsfreecalls/CallsFreeCalls/bin/CallsFreeCalls-debug.apk
    adb shell am start -a android.intent.action.MAIN -n com.yourapphere/.MainActivity

    this is install on connected device and check all changes in source.

    and compiler output u can see:
    - in xcode alert – filename and short description
    in build log detailed explanation, with line number:

    [javac] Compiling 1 source file to //bin/classes
    [javac] /AccountRegistrationChanged.java:49: ‘;’ expected
    [javac] Str ing sender = local.getStringExtra(“sender”);
    [javac] ^
    [javac] 1 error

    not bad, but what about device logs (i don’t like to avoid them)

    go to edit scheme -> Build -> Post-Actions and add script:

    #!/bin/ti

    osascript -e ‘
    tell application “Terminal”
    activate
    tell window 1
    do script “adb logcat | grep -E \”YOU_FIRST_TAG|YOU_SECOND_TAG|YOU THIRD TAG\”"
    set win_id to id
    end tell

    set w_ids to (id of every window)

    repeat while w_ids contains win_id
    delay 1
    set w_ids to (id of every window)
    end repeat
    end tell’

    Xcode will opened terminal with sorted logs inside! In my case, i must using TAGs bcs i have 2 processes inside app and second process will be started after 30 seconds (i don’t like to missed logs from first process while second started). In you case you can catch process PID – simply look in stackoverflow and grep by process PID – you will see all logs in terminal window.

    i was try to look around possibility to using current opened terminal to add tab, start command execution, but it was not success – somebody from this post can post real code.

    don’t forget to look at http://www.callsfreecalls.com :)

RSS feed for comments on this post.

Sorry, the comment form is closed at this time.

Powered by WordPress

Switch to our mobile site