"Why doesn't Robolectric just use the real Android jars?" This one of the most commonly asked questions. The short answer is that it's hard: hard to get the real Android jars, hard to hook them up, hard to deal with native code, hard to know what the heck is going to happen when real code is called, hard to change from the Shadow-way of doing things, hard hard hard.
But, many of you know that we have a branch at http://github.com/pivotal/robolectric named "reviscerated" that backs Robolectric with real Android implementations. This branch has languished due to lack of time and resources.
This week we spent time reviving this branch, merging the master branch into it and getting it working with APK 10/2.3.3 jars.
Robolectric tests pass in both SDK and real-jars mode, as do the tests in RobolectricSample. Now we need you to help us test this code. If you find it valuable then help us fix what's broken.
So, what happens?
All non-Shadowed entities, such as methods and classes, call through to the real Android implementations. No more "Stub!" exceptions from Android, no more null return values or no-op implementations from Robolectric -- if you call Android code, you get Android code. Note that any methods implemented in a Shadow are still called -- shadowed things win.
Essential Android Links:
- Building in general: http://source.android.com/source/initializing.html
- List of Android names, branches, tags: http://source.android.com/source/build-numbers.html
- List of Android projects: http://android.git.kernel.org/. When the docs say
repo sync [PROJECT1] [PROJECT2]they mean this list. For example,
repo sync platform/build device/common
- SDK jars: These are the jars installed by android using AVD or command line tools. Implementations replaced with "Stub!" exceptions and entities annotated @hide are either non-public or otherwise unavailable.
- real jars: Jars generated by manually building Android. Full implementations present including entities annotated @hide.
Getting The Real Jars
Google does not distribute the real Android jars -- you must build them yourself.
Setting up your Workstation
Follow Mac setup instructions here: http://source.android.com/source/initializing.html
After create and mount (double-click) the sparse image, make a directory specifically for the version of Android you want to build.
Note: once you have built one version of android it is is hard to use that same dir to build another version. I don't know how to clean up from the last version. It's hit-or-miss.
See the build instructions here: http://source.android.com/source/building.html
Note: make sure the
lunchoutput looks right! If the numbers don't match what you expect from http://source.android.com/source/build-numbers.html then you have synced to the wrong version and will need to
repo sync -b [some other tag]
Don't Wait: Watch for classes.jar
The build takes about 20-30+ minutes, but you don't have to wait for the full build. Watch for
classes.jar.When it appears you can grab it and move it somewhere handy:
Also: download kxml2-2.3.0.jar and put it in the same directory you moved classes.jar. http://www.findjar.com/jar/net/sf/kxml/kxml2/2.3.0/kxml2-2.3.0.jar.html
Using the Jars with Robolectric
From Maven 2.0-SNAPSHOT
Download the jars from here: https://oss.sonatype.org/content/repositories/snapshots/com/pivotallabs/robolectric/2.0-SNAPSHOT/
From Robolectric Source
Open RobolectricTestRunner.USE_REAL_ANDROID_SOURCESand make sure it is set to
- Look at
RobolectricTestRunner.getDefaultLoader()and make sure the paths point to the real jars you copied above. You can also use environment variables for these. See Setting ANDROID_HOME and ANDROID_REAL_JARS_HOME below.
- Rebuild the jars in real-jar mode:
- Replace your robojectric.jar with
target/robolectric.jar or target/robolectric-all.jar
If you are using IntelliJ you might need to fix the Project Structure => Modules => Dependencies.
Setting ANDROID_HOME and ANDROID_REAL_JARS_HOME
You need to tell Robolectric some extra information when in real-jars mode. At this time you can either hand-edit
RobolectricTestRunnerand change the defaults or set environment variables:
Intellij most likely won't see those variables. Set them in the run configruation or default run configuration for JUnit:
- Real jars mode seems to be incompatible with Roboguice at the moment. Sometimes it works, somtimes not.
ant clean testresults in MethodGenerator test failures --
mvn clean testsucceeds.
- We would like to find the minimum time and effort to generate real jars.
- There are likely errors in this blog post. We will be updating it as issues are found.