Robolectric updated to Jelly Bean (API 16)

215 views
Skip to first unread message

Michael Portuesi

unread,
Sep 17, 2012, 3:23:09 PM9/17/12
to robol...@googlegroups.com
Hi there,

A week or so ago, the Maven public repos put up an android.jar file built against the Jelly Bean (API 16) sources.  So I have updated Robolectric to build against the API 16 version of android.jar and I've pushed those changes to the pivotal master repo.

It appears that Google may have eliminated, not just deprecated, a few entry points from the WebSettings class in API 16.  So if you have tests that use WebSettings you may possibly run into issues. If so, please post to this group and I'll try to help sort things out.

Regards,
Michael Portuesi

sd2011

unread,
Oct 23, 2012, 5:43:40 PM10/23/12
to robol...@googlegroups.com
Hi Michael,
i think my issue might be related...is there a way you can take a look and provide guidance? 
I just posted my question before finding your post on the same forum.

Michael Portuesi

unread,
Oct 23, 2012, 6:38:20 PM10/23/12
to robol...@googlegroups.com
Hi there sd2011,

You are correct that WebSettings became an abstract class in API 16.

At API 16, Robolectric could no longer create an instance of WebSettings via:

private WebSettings webSettings = Robolectric.newInstanceOf(WebSettings.class);

because WebSettings is abstract and cannot be instantiated even by reflection.

Because WebSettings became abstract, Robolectric has to somehow offer a concrete instantiation of WebSettings.  So I created the android.webkit.TestWebSettings class, and made Robolectric return an instance of that in ShadowWebView#getSettings.

There's some things I don't like about this approach:

1) TestWebSettings resides in the android.webkit package, and not in any Robolectric package.  That's because Google, in their infinite wisdom, made the constructors for WebSettings package-protected, and so any subclass must reside in the same package as WebSettings.

2) The ShadowWebSettings class went away entirely, with all of its code moving into TestWebSettings.  I got rid of ShadowWebSettings mainly because I didn't want two copy/paste implementations of the same code lying around in Robolectric - it would have been a maintenance nightmare waiting to happen.  (There may also have been either a compile-time or runtime problem with keeping a shadow for an abstract class, but my memory is hazy).

As to the problem you reported in your StackOverflow post -  that you switched to API 12 but still cannot instantiate WebSettings.  This is likely to be the case even if you change your project to a lower API level, because Robolectric itself is still built against the android-16.jar.  If you change Robolectric itself to build against android-12.jar, you will get an instance of WebSettings - but without a shadow implementation because ShadowWebSettings has been removed from the current version of Robolectric.

The easiest workaround for your problem would probably be to update your project to API 16, and then instantiate a TestWebSettings object directly in your test case.  So instead of:

private WebSettings webSettings = Robolectric.newInstanceOf(WebSettings.class);

you would write:

    private WebSettings webSettings = new TestWebSettings();

Robolectric ideally should have some type of mechanism that allows it to serve up one of several alternate implementations of WebSettings based upon Android API level.  What I'm not yet convinced of is whether the resulting source code can build against any Android API jar without modification, or whether we would need to build several jar files for Robolectric, one targeting each version of the API.

Best regards,
Michael Portuesi

sd2011

unread,
Oct 23, 2012, 7:00:44 PM10/23/12
to robol...@googlegroups.com
Hi Michael
Thank you for your reply, and all the details you provided.  I almost cried when I saw your reply, as I have been stuck by this for a while now.
What you said totally makes sense, I also tried  to create my own concrete class of WebSettings, but like you said, it is package protected, so my approach failed.

I was wondering where I can find your TestWebSettings class?
I assume I don't have it and i need to get it somewhere, I was browsing manually https://github.com/pivotal/robolectric
but I could not find it...(is there a search button)?

Thanks


On Monday, September 17, 2012 12:23:09 PM UTC-7, Michael Portuesi wrote:

sd2011

unread,
Oct 23, 2012, 7:03:29 PM10/23/12
to robol...@googlegroups.com

Michael Portuesi

unread,
Oct 23, 2012, 7:15:25 PM10/23/12
to robol...@googlegroups.com
Eric,

Please accept my apology for causing you an inconvenience, and I'm glad I could be helpful.

In the short term, I will see if there's a simple way the ShadowWebSettings class can be re-introduced so that Robolectric can serve lower API levels.  I think the immediate reason why I took it out (other than code duplication) is that since ShadowWebSettings was shadowing an abstract class, that it was failing the Robolectric wiring tests.  I'll have to repeat that experiment to see what can be done.

Regards,
Michael Portuesi

sd2011

unread,
Oct 23, 2012, 8:19:09 PM10/23/12
to robol...@googlegroups.com
No apologies needed Michael!  What you did and said made sense.  It's just that i become panicky when i could not find any solution to this initially, i am glad i asked it here and not just stack overflow.  Nonetheless, thank you for your speedy replies and thoughts on this issue...i looked for a solution and i got it...all good now

thanks again Michael
Reply all
Reply to author
Forward
0 new messages