Android SDK Source Code for your IDE

“There was nothing you could have done, Luke, had you been there. You’d have been killed too, and the droids would now be in the hands of the Empire.”

While the Android SDK comes with a complete set of javadocs, the source code of the SDK is missing in the SDK distribution. This is very unfortunate, since you cannot easily debug into SDK methods (at least not without running into de-compiled code) nor can you see how things actually work.

Eclipse - Source Not Found

However, there is a quick fix to that problem. I downloaded the complete Android source including the Linux, drivers, libs, etc., like explained here: http://source.android.com/source/download.html and ran small Java program on the source tree. I used to this with a simple bash script but over the last couple of Android Releases, the java source locations got a little more diverse and I started missing a couple files. So instead, this Java program walks the source tree and looks for java source files. All those will then be copied into a new location, considering their package name. Finally, the jar tool gets called to put all the source into a single bundle for easier handling.

package com.techcasita.tools;
import java.io.*;
/**
 * Find all of Android's Java Sources, consider their package names,
 * and place it in a jar file.
 *
 * @author <a href="mailto:wolf@wolfpaulus.com">Wolf Paulus</a>
 */
public class DroidSource {
    private static String TargetPath;

    public static void main(String[] args) {
        if (args.length == 2 &amp;&amp; new File(args[0]).isDirectory()) {
            DroidSource.TargetPath = args[1];
            File t = new File(args[1]);
            if ((t.exists() &amp;&amp; t.isDirectory() &amp;&amp; t.listFiles().length == 0) || t.mkdir()) {
                traverse(new File(args[0]));
                try {
                    Runtime.getRuntime().exec("jar cf " + t.getParentFile().getAbsolutePath()
+ File.separatorChar + "android-10-src.jar -C " + TargetPath + File.separatorChar + " .");
                } catch (IOException e) {
                    e.printStackTrace();
                }
            } else {
                System.out.println("Usage: " + DroidSource.class.getName()
+ "  ");
                System.out.println(" should exist and be empty");
            }
        } else {
            System.out.println("Usage: " + DroidSource.class.getName()
+ "  ");
        }
    }

    static void traverse(File file) {
        if (file != null &amp;&amp; !file.isHidden()) {
            if (file.isDirectory()) {
                if (!"out".equals(file.getName())) {
                    File[] files = file.listFiles();
                    for (File f : files) {
                        traverse(f);
                    }
                }
            } else if (file.getName().endsWith("java")) {
                String path = findPackage(file);

                if (path != null) {
                    path = path.replace('.', File.separatorChar);
                    createDirs(path);
                    copyFile(file.getAbsolutePath(), TargetPath + File.separatorChar
+ path + File.separatorChar + file.getName());
                }
            }
        }
    }

    private static String findPackage(File file) {
        final String TAG0 = "package ";
        final String TAG1 = ";";
        char[] buffer = new char[2048];

        try {
            FileReader r = new FileReader(file);
            r.read(buffer);
            StringBuffer sb = new StringBuffer();
            sb.append(buffer);
            int t0 = sb.indexOf(TAG0);
            if (t0 &lt; 0) return null;
            t0 += TAG0.length();
            int t1 = sb.indexOf(TAG1, t0);
            if (t1 &lt; 0) return null;
            if (t1 &gt; sb.indexOf(" ", t0)) return null;
            return sb.substring(t0, t1);
        } catch (IOException e) {
            return null;
        }
    }

    private static void createDirs(String path) {
        String[] sa = path.split("" + File.separatorChar);
        String name = TargetPath;
        for (String s : sa) {
            name += File.separatorChar + s;
            File f = new File(name);
            if (!f.exists()) {
                f.mkdir();
            }
        }
    }

    private static void copyFile(String srFile, String dtFile) {
        try {
            File f1 = new File(srFile);
            File f2 = new File(dtFile);
            InputStream in = new FileInputStream(f1);
            OutputStream out = new FileOutputStream(f2);

            byte[] buf = new byte[1024];
            int len;
            while ((len = in.read(buf)) &gt; 0) {
                out.write(buf, 0, len);
            }
            in.close();
            out.close();
        } catch (FileNotFoundException ex) {
            System.out.println(ex.getMessage() + " in the specified directory.");
            System.exit(0);
        } catch (IOException e) {
            System.out.println(e.getMessage());
        }
    }
}

This will generate this android-10-src.jar, (36 MB) containing all the relevant java sources and after attaching it to the SDK classes in your favorite IDE (IntelliJ in my case) you can easily step into the code, for instance during a debug session… The jar was generated from the 2-3 tag here http://android.git.kernel.org on July 1st, 2011.

6 Responses to “Android SDK Source Code for your IDE”

  1. wisdomsprince says:

    You have seriously done a great service. You saved me sooo much time. Thank you!

  2. Grateful says:

    Ditto

  3. Thanks a million, especially since kernel.org is down right now :)

  4. OK, I’ll admit I just used your jar – that got me up and running in almost no time. I’ll keep this code in mind if I need to debug something version-specific though. Thank you!

  5. woot thanks ,used your jar :) would love to see 3.x and 4.x versions too :)

Leave a Reply

Your email address will not be published. Required fields are marked *

*

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