Help with BroadcastReceiver

535 views
Skip to first unread message

Paul Butcher

unread,
Nov 22, 2010, 9:50:29 AM11/22/10
to robo...@googlegroups.com
The application that I'm working on has a BroadcastReceiver which receives AlarmManager broadcasts. I would like to call code that relies upon RoboGuice, but am currently stymied by the fact that BroadcastReceiver has no "getApplication" method or similar. How do I get an injector in this circumstance?

Many thanks in advance for any help you can offer!

--
paul.butcher->msgCount++

Snetterton, Castle Combe, Cadwell Park...
Who says I have a one track mind?

http://www.paulbutcher.com/
LinkedIn: http://www.linkedin.com/in/paulbutcher
MSN: pa...@paulbutcher.com
AIM: paulrabutcher
Skype: paulrabutcher

Donn Felker

unread,
Nov 22, 2010, 10:07:19 AM11/22/10
to robo...@googlegroups.com
Paul,

You can do it like this (this is how I've done it in one of my DbHelpers that is way down in the object graph:

Use the "Provider<>" 

@Inject
public DbHelper(Provider<Application> contextProvider) {
super(contextProvider.get(), DB_NAME, null, DB_VERSION);

}



Donn Felker
Author of Android App Dev for Dummies & Intro to Android Development (tekpub.com)
Microsoft ASPInsider, MCTS, MCP, CSM, ITIL
http://blog.donnfelker.com
http://twitter.com/donnfelker



--
You received this message because you are subscribed to the Google Groups "roboguice" group.
To post to this group, send email to robo...@googlegroups.com.
To unsubscribe from this group, send email to roboguice+...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/roboguice?hl=en.


Donn Felker

unread,
Nov 22, 2010, 10:17:17 AM11/22/10
to robo...@googlegroups.com
I just realized I may have not answered your question. If this doesnt help, please let me know! Sorry for any confusion!

Donn Felker
Author of Android App Dev for Dummies & Intro to Android Development (tekpub.com)
Microsoft ASPInsider, MCTS, MCP, CSM, ITIL
http://blog.donnfelker.com
http://twitter.com/donnfelker


Paul Butcher

unread,
Nov 22, 2010, 10:25:44 AM11/22/10
to roboguice
On Nov 22, 3:07 pm, Donn Felker <d...@donnfelker.com> wrote:
> You can do it like this (this is how I've done it in one of my DbHelpers
> that is way down in the object graph:
>
> Use the "Provider<>"
>
>         @Inject
>         public DbHelper(Provider<Application> contextProvider) {
>                 super(contextProvider.get(), DB_NAME, null, DB_VERSION);
>
>         }

Thanks Donn. Apologies, but I'm clearly missing something. If I have a
provider, that will help me to get an application. But how do I get a
provider in the first place?

I suspect that I'm missing something very simple (blush) so please
forgive me for being dense.

Michael Burton

unread,
Nov 22, 2010, 5:29:59 PM11/22/10
to robo...@googlegroups.com
Hi Paul,

I just checked in a preliminary version of RoboBroadcastReceiver on the default branch. Give that a try and let me know if that works for you. I did a quick test and it seems to work for me, but it hasn't been rigorously tested yet.

Cheers,
Mike

PS. Will look at your patches soon, thanks for the contribution!

Paul Butcher

unread,
Nov 23, 2010, 8:07:55 AM11/23/10
to robo...@googlegroups.com
Thanks, Mike. It never occurred to me that the application context
would actually *be* the application object. Obvious in retrospect, I
guess!

Thanks!

Sent from my iPhone, so apologies if I'm a little terse.

Paul Butcher

unread,
Dec 10, 2010, 8:18:19 AM12/10/10
to roboguice
On Nov 22, 10:29 pm, Michael Burton <m...@niskala.org> wrote:
> PS. Will look at your patches soon, thanks for the contribution!

Any word on this, Mike? Right now, we're using our own hacked version
of RoboGuice, and ideally I'd like to move onto the "official" release
ASAP.

Thanks!

--
paul.butcher->msgCount++
Snetterton, Castle Combe, Cadwell Park...
Who says I have a one track mind?
http://www.paulbutcher.com/
LinkedIn: http://www.linkedin.com/in/paulbutcher
MSN: p...@paulbutcher.com
AIM: paulrabutcher
Skype: paulrabutcher

Michael Burton

unread,
Dec 14, 2010, 12:21:44 PM12/14/10
to robo...@googlegroups.com
Hi Paul,

Thanks for the kick in the pants.  I just gave it a try but I'm having trouble with your changes in my own testcases.  When I replaced my roboguice with yours, I got the following error:

java.lang.NoSuchMethodException: GrouponTestApplication(Context)
at java.lang.Class.getMatchingConstructor(Class.java:660)
at java.lang.Class.getConstructor(Class.java:477)
at roboguice.test.RoboUnitTestCase.setUp(RoboUnitTestCase.java:50)
at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:169)
at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:154)
at android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:520)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1447)

So I added roboguice as a dependency in my test project, which fixed that problem but caused the following problem:



java.lang.RuntimeException: Exception during suite construction
at android.test.suitebuilder.TestSuiteBuilder$FailedToCreateTests.testSuiteConstructionFailed(TestSuiteBuilder.java:239)
at java.lang.reflect.Method.invokeNative(Native Method)
at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:169)
at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:154)
at android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:520)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1447)
Caused by: java.lang.reflect.InvocationTargetException
at com.groupon.test.tests.AuthenticationTests.<init>(AuthenticationTests.java:29)
at java.lang.reflect.Constructor.constructNative(Native Method)
at java.lang.reflect.Constructor.newInstance(Constructor.java:446)
at android.test.suitebuilder.TestMethod.instantiateTest(TestMethod.java:87)
at android.test.suitebuilder.TestMethod.createTest(TestMethod.java:73)
at android.test.suitebuilder.TestSuiteBuilder.addTest(TestSuiteBuilder.java:263)
at android.test.suitebuilder.TestSuiteBuilder.build(TestSuiteBuilder.java:185)
at android.test.InstrumentationTestRunner.onCreate(InstrumentationTestRunner.java:373)
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4218)
at android.app.ActivityThread.access$3000(ActivityThread.java:125)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2071)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:123)
at android.app.ActivityThread.main(ActivityThread.java:4627)
at java.lang.reflect.Method.invokeNative(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NoClassDefFoundError: com.groupon.activity.TodaysDeal
... 19 more


It appears that all of my injections are now happening in the test project instead of the app project, and therefore the guice classloader doesn't have access to the app classes.

Is this expected?

Cheers,
Mike

Manfred Moser

unread,
Dec 14, 2010, 12:46:07 PM12/14/10
to robo...@googlegroups.com
With regards to the new release. Guice 3.0 is getting pretty close and
will be deployed in Maven central including the no-aop version. Are we
going to move Roboguice to it. I have it building fine in my clone and
will update it one the final version is out..

manfred

Michael Burton

unread,
Dec 14, 2010, 12:52:18 PM12/14/10
to robo...@googlegroups.com
Yeah, I was thinking about doing a test after xmas to see how well groupon builds and runs with guice 3.0. How was your experience been with it so far? Does it increase your app size noticeably? Does it change performance as far as you can tell?

--
http://about.me/michaelburton

Manfred Moser

unread,
Dec 14, 2010, 12:57:20 PM12/14/10
to robo...@googlegroups.com
... well.. I only build roboguice and astroboy... have not done any
further testing. Its on my todo list as well ;-)

Paul Butcher

unread,
Dec 14, 2010, 1:07:18 PM12/14/10
to robo...@googlegroups.com
Honestly, Mike, I have no clue what's going on whatsoever. The changes that I've made to RoboUnitTestCase are really simple. Here are the diffs:


(embarrassingly, I noticed that I checked in spurious spaces at the beginning of the source, so the diffs were much more extensive than they should have been - I've just pushed a change to undo that)

I don't understand how this change could require a change to your dependencies, or to which project injections will be made within?
MSN: pa...@paulbutcher.com
AIM: paulrabutcher
Skype: paulrabutcher

Michael Burton

unread,
Dec 14, 2010, 1:38:27 PM12/14/10
to robo...@googlegroups.com
I don't have time to look into this at the moment, but if I had to speculate I'd say that setupTest is running in the test project class loader, while the individual test methods are running in the app project class loader.

I'm surprised this change is working for you, actually.  What motivated the change?  Do you have any sample test classes that use your changes that I could take a look at?

Paul Butcher

unread,
Dec 15, 2010, 7:07:55 AM12/15/10
to robo...@googlegroups.com
On 14 Dec 2010, at 18:38, Michael Burton wrote:
> I don't have time to look into this at the moment, but if I had to speculate I'd say that setupTest is running in the test project class loader, while the individual test methods are running in the app project class loader.

Ah! I forgot that our situation is unusual - we're testing a library project, not a separate application. Our setup is described in the following blog post:

http://www.paulbutcher.com/2010/09/android-library-project-with-tests-step-by-step/

> I'm surprised this change is working for you, actually. What motivated the change? Do you have any sample test classes that use your changes that I could take a look at?

You and I discussed the motivation a few months ago, in the following conversation :-)

http://groups.google.com/group/roboguice/browse_thread/thread/df4488cad908cf70#anchor_f22d6321ca4e3d82

Basically several of our tests set up a fixtures that require an injector to do so. Here's one example:

We have a class called "Predictor" (which, surprise!, makes predictions). It supports a listener (I won't go into the detail of what this listener does, as it's not relevant to this discussion). To avoid having to register a listener at the start of each test, we have the following in PredictorImplTest:

> public class PredictorImplTest extends RoboUnitTestCase<HarnessApplication> {
>
> class PredictorListenerImpl implements PredictorListener {
> // ...
> }
>
> PredictorListenerImpl listener = new PredictorListenerImpl();
> PredictorImpl predictor;
>
> @Override
> public void setUp() throws Exception {
> super.setUp();
>
> predictor = getInjector().getInstance(PredictorImpl.class);
> predictor.addListener(listener);
> }
>
> @Override
> public void tearDown() throws Exception {
> predictor.removeListener(listener);
> }
>
> // Tests that use predictor and listener go here
> }

Clearly we could move the setUp and tearDown code out into the individual test functions, but would prefer to avoid doing so if possible. Perhaps it won't be possible though :-(

Michael Burton

unread,
Dec 17, 2010, 3:05:36 PM12/17/10
to robo...@googlegroups.com
It sounds like what you've got going is working from you.   I'm thinking that the best thing to do is to split out those two functions (testing of android app and testing of library apps) into two separate test classes.

I suggest you keep the code that works, only move it to your own test package instead of modifying roboguice directly.  I've filed a bug to think about what sort of injection we want to support in the test context.  It's come up before, so it sounds like something people are interested in.  Perhaps it's as simple as creating a second class with injection performed during setUp(), but I suspect it's not that simple.


Cheers,
Mike
Reply all
Reply to author
Forward
0 new messages