If you are working with the Android Development Toolkit (ADT) for Eclipse you may have noticed that the sources for android.jar are missing.
The Android SDK comes without the sources, and even if you manage to download the source code for the Android library, the ADT does not allow you to attach the sources to the library in the IDE. When debugging or navigating into the sources of android classes this may be similar to what you'll get:

Class File Editor

The trick, how explained here, is to download the sources and copy them into android-sdk/platforms/android-X/sources folder (where X is the API version).

For example, supposing I've installed the SDK into ~/opt/android-sdk-mac_86 on my Mac, and I am developing an application with Android 1.5 (API level 3). I should download the source files from Android website using git. Then I need to checkout the sources with tag name "android-sdk-1.5_r3", collect all the source files and move them into the directory ~/opt/android-sdk-mac_86/platforms/android-3/sources.

Here's my source tree under android-sdk-mac_86/platforms; in red color the directory where to put the sources:

luigi@hal9000:~/opt/android-sdk-mac_86$ tree -L 2  platforms
platforms/
|-- android-3
|   |-- android.jar
|   |-- build.prop
|   |-- data
|   |-- framework.aidl
|   |-- images
|   |-- samples
|   |-- skins
|   |-- source.properties
|   |-- sources
|   |-- templates
|   `-- tools
|-- android-4
|   `-- ...
|-- android-6
|   `-- ...
`-- android-7
    `-- ...

Creating a directory and copy some files inside it's not much complicate. But once you downloaded the sources, you'll discover that they are spread in several sub-directories. Also you need some practice with git command line utility to download the sources check available tags, switch to the proper source tree, then package all the source files into a folder or an archive.

I created following script, which runs on OSX (and hopefully on Linux as well).

luigi@hal9000:~$ cat bin/android-src-build.sh
 
#!/bin/sh 

SRC_DIR=/tmp/android-api

print_syntax() {
   echo "Syntax:\n\t$(basename $0) [option]"
   echo "\nOptions:"
   echo "\t-l prints available versions"
   echo "\t-v builds jar file with sources of specified version"
   echo "\t-c cleans up the sources from the temp directory\n"
   exit 1
}

error() {
   echo "Error:" $1
   exit 1
}

download_sources() {
    if [[ ! -d $SRC_DIR ]]; then
        git clone git://git.source.android.com/platform/frameworks/base $SRC_DIR 
    fi
}

if ! which git > /dev/null ; then
    error "git not installed (or not in the PATH)"
fi

if ! which jar > /dev/null ; then
    error "jar not installed (or not in the PATH)"
fi

if [[ "$1" == "-l" ]]; then
    download_sources
    cd $SRC_DIR
    git tag -l   
    exit 0;
fi

if [[ "$1" == "-c" ]]; then
    rm -rf $SRC_DIR
    exit 0;
fi

if [[ "$1" == "-v"  && ! -z "$2"  ]]; then
    JAR_FILE=$(pwd)/$2-src.jar
    download_sources
    cd $SRC_DIR
    if ! git tag -l | grep $2 ; then
        echo "Version \"$2\" not found" 
        exit 1;
    fi
    git checkout $2
    touch $JAR_FILE
    find . -depth 2 -name "java" -type d -exec jar uf $JAR_FILE -C {} . \;
    exit 0
fi

print_syntax

You can download it here: android-src-build.sh.gz. (It's a bash script: download and execute it at your own risk!)

The script, is able to download the sources from the Android git repository, and, given the version number it packs it into a jar file, that can be lately be unpacked into the sources folder of the Android SDK, where indicated above.

When you run it without parameters it gives you following help:

luigi@hal9000:~$ android-src-build.sh 
Syntax:
        android-src-build.sh [option]

Options:
        -l prints available versions
        -v builds jar file with sources of specified version
        -c cleans up the sources from the temp directory

The -l parameter prints the list of available versions. If the sources have not been already downloaded, the -l will also download them. So the first time, it will take some minutes before displaying the available releases:

luigi@hal9000:~$ android-src-build.sh -l
Initialized empty Git repository in /private/tmp/android-api/.git/
remote: Counting objects: 106183, done.
remote: Compressing objects: 100% (35592/35592), done.
remote: Total 106183 (delta 61793), reused 104978 (delta 60893)
Receiving objects: 100% (106183/106183), 128.07 MiB | 1.52 MiB/s, done.
Resolving deltas: 100% (61793/61793), done.
Checking out files: 100% (8431/8431), done.
android-1.0
android-1.5
android-1.5r2
android-1.5r3
android-1.5r4
android-1.6_r1
android-1.6_r1.1
android-1.6_r1.2
android-1.6_r1.3
android-1.6_r1.4
android-1.6_r1.5
android-1.6_r2
android-2.0.1_r1
android-2.0_r1
android-2.1_r1
android-2.1_r2
android-2.1_r2.1p
android-2.1_r2.1p2
android-2.1_r2.1s
android-sdk-1.5-pre
android-sdk-1.5_r1
android-sdk-1.5_r3
android-sdk-1.6-docs_r1
android-sdk-1.6_r1
android-sdk-1.6_r2
android-sdk-2.0.1-docs_r1
android-sdk-2.0.1_r1
android-sdk-2.0_r1
android-sdk-2.1_r1
android-sdk-tools_r2
android-sdk-tools_r3
android-sdk-tools_r4
android-sdk-tools_r5

Now, let's say that we are developing on Android 1.5, we may want to create a jar file containing all the java sources for that version with:

luigi@hal9000:~$ android-src-build.sh -v android-sdk-1.5_r3
android-sdk-1.5_r3
Note: moving to 'android-sdk-1.5_r3' which isn't a local branch
If you want to create a new branch from this checkout, you may do so
(now or later) by using -b with the checkout command again. Example:
  git checkout -b 
HEAD is now at b69bed1... AI 150122: Merge from donut.   Fix permissions issue for uninstall of updated system applications.   If an existing update for a system application is uninstalled, when reverting back to the existing   version in system partition, permissions have to be granted again.   BUG=1893639
luigi@hal9000:~$ ls -l *.jar
-rw-r--r--  1 luigi  staff  4766477 May 17 15:59 android-sdk-1.5_r3-src.jar

As shown above, after issuing the command a file called android-sdk-1.5_r3-src.jar will be generated into the current directory.
Now the only thing remaining is to expand this file into the folder ~/opt/android-sdk-mac_86/platforms/android-3/sources:

luigi@hal9000:~$ rm -rf /Users/luigi/opt/android-sdk-mac_86/platforms/android-3/sources/
luigi@hal9000:~$ mkdir ~/opt/android-sdk-mac_86/platforms/android-3/sources 
luigi@hal9000:~$ cd ~/opt/android-sdk-mac_86/platforms/android-3/sources
luigi@hal9000:~/opt/android-sdk-mac_86/platforms/android-3/sources$ jar xf ~/android-sdk-1.5_r3-src.jar

At this point, restarting eclipse should be enough to have the ADT linked with the source files.

About the platforms available into the Android SDK, under the platform directory, there are following folders: android-3, android-4, android-6, and adroid-7.
I am not 100% sure, but they should correspond to the source code identified respectively by following table:

android-3 = android-sdk-1.5_r3
android-4 = android-sdk-1.6_r2
android-6 = android-sdk-2.0.1_r1
android-7 = android-sdk-2.1_r1

Finally, if you want to remove the sources downloaded you can run the script with the -c (clean) option: it will remove the sources stored temporarily into the folder /tmp/android-api:

luigi@hal9000:~$ android-src-build.sh -c
(no output returned)

Alternatively, you may want to remove the files manually.

Now, after a refresh (or a restart) from Eclipse, the sources from Android classes should look much better:

Sample Android Source

Check the referenced articles for further information on how to download the android sources, and how the ADT plugin for Eclipse locates the sources for the Android SDK.

I really think that Google should release the sources nicely packed as per the android.jar and make sure they are properly referenced by the ADT. Since then, this is my way.

For questions, mistakes, etc. leave a comment.

References

- Browsing Android Source in Eclipse
- Android sources


12 Responses to “Attaching sources to android.jar in Eclipse”  

  1. 1 weiguo

    Previous HEAD position was 0188950… Properly implement Paint.breakText for layoutlib. (do not merge)
    HEAD is now at 63ee17a… Merge branch ‘eclair’ into eclair-release
    find: paths must precede expression: 2
    Usage: find [-H] [-L] [-P] [-Olevel] [-D help|tree|search|stat|rates|opt|exec] [path…] [expression]

    when run with
    -v android-sdk-x.x_r1, I got above error

    ubuntu, Google recommended platform

  2. 2 Luigi

    @weiguo

    try this.

    Substitute line 1 with
    #!/bin/bash

    and line 57 with

    find . -maxdepth 2 -name “java” -type d -exec jar uf $JAR_FILE -C {} . \;

    in linux the -depth has to be substituted with -maxdepth

    if this still doesn’t work, download the jar files directly from here:
    http://en.newinstance.it/2010/05/18/androidjar-sources/

  3. 3 Anm

    Struggling to apply this to 2.2. It seems to be stuck on a git error. Any help (or a updated script) would be helpful.


    $ android-src-build.sh -v android-2.2_r1
    android-2.2_r1
    android-2.2_r1.1
    Note: moving to 'android-2.2_r1' which isn't a local branch
    If you want to create a new branch from this checkout, you may do so
    (now or later) by using -b with the checkout command again. Example:
    git checkout -b
    HEAD is now at 71beeab... Properly note the current active restore set's token
    $ android-src-build.sh -v android-2.2_r1
    android-2.2_r1
    android-2.2_r1.1
    HEAD is now at 71beeab... Properly note the current active restore set's token
    $ android-src-build.sh -v android-2.2_r1.1
    android-2.2_r1.1
    Previous HEAD position was 71beeab... Properly note the current active restore set's token
    HEAD is now at 34c0b2e... Verify hostname where possible, and clarify where not.

  4. 4 Luigi

    Anm, if I have the chance to have a look I will fix it. Unfortunately, at the moment I am not working on Android.

  5. 5 Chris Lesner

    For cygwin and linux the find line should be:

    find . -maxdepth 2 -name “java” -type d -exec jar uf $JAR_FILE -C {} . \;

  6. 6 Chris Lesner

    For cygwin one also needs to make:

    JAR_FILE=`cygpath -w $(pwd)/$2-src.jar`

    And in the comment above:
    find . -maxdepth 2 -name “java” -type d -exec jar uf $JAR_FILE -C {} . \;

    should be:
    find . -maxdepth 2 -name “java” -type d -exec jar uf $JAR_FILE -C {} . \;

    the very slight but important difference is the quotes around java.

  7. 7 Luigi R. Viggiano

    Thanks Chris!

  8. 8 Andreas N

    Thanks for the great detailed info! Worked first time for me! Win!

  9. 9 Mike M

    Thank you for the script. On my Mac it works like a charm.
    I only made two small changes:

    in print_syntax I added the -e option to echo because it was necessary for my bash shell. Otherwise the \t and \n were printed out instead of interpreted.

    But more important I added
    jar uf $JAR_FILE -C ./test-runner/src .
    just after find in download_sources. This adds the sourcefiles for the JUNIT Tests and the Mockup-Files.

  10. 10 peter

    Thanks for the script, with some minor modification, it works.
    On Ubuntu 11.4 (pretty much Debian-variant), they have make
    /bin/sh -> /bin/dash
    and your script is pretty much based on bash, which will have error in dash.

    so, i edit the first line: #!/bin/bash
    and also the find . -maxdepth (was -depth)

    a bit long for downloading all source, wondering whether it is necessary or any shortcut?

    anyway it works, thanks man.

  1. 1 Android.jar sources - NewInstance
  2. 2 Исходники Android SDK « KrOlSer’s Weblog


Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>



Calendar

May 2010
M T W T F S S
« Apr   Jun »
 12
3456789
10111213141516
17181920212223
24252627282930
31  

Follow me

twitter flickr LinkedIn feed

Subscribe by email

Enter your email address:

Archives


Categories

Tag Cloud


Listening