3

Is there any way how to get a reference for a BroadcastReceiver defined in Manifest.xml from code?

In my case, we are using a BroadcastReceiver that needs to be included in the Manifest.xml. However it has functionality I would like to reuse from within our code. So instead of creating another similar BroadcastReceiver and instantiating it from the code I would like to obtain a reference to the existing one.

Additional information:

My goal is to subscribe to an event on my BroadcastReceiver from my activity - an event that I would like to reuse - instead of creating another instance of this receiver in my activity I would like to obtain a reference to the existing one.

Jakub Holovsky
  • 6,543
  • 10
  • 54
  • 98
  • 1
    A Receiver class registered in the manifest has no continuously existing instance. A new instance is created every time it needs to process a broadcast. If you want to use the same class in your `Activity`, just create your own `new` instance, and register it dynamically. – Mike M. Jul 18 '16 at 09:49
  • 1
    @MikeM. could you please post this as an answer, exactly what i was looking for. – Jakub Holovsky Jul 18 '16 at 09:58

2 Answers2

4

When registering a BroadcastReceiver in the manifest, you're registering the class, not an instance of it. Each time a broadcast occurs that your <receiver> needs handle, a new instance is created to do so, so you can't really get a reference to one as you're describing.

It's perfectly fine to dynamically instantiate and register an instance of a Receiver class that you've also statically registered in the manifest. I would note, though, that if the statically registered class is going to be run anyway - that is, if it's going to handle the same broadcasts as the dynamically registered one - you might consider just notifying your Activity from the Receiver class - e.g., with LocalBroadcastManager, another event bus implementation, etc. - instead of essentially duplicating Receivers.

Mike M.
  • 38,532
  • 8
  • 99
  • 95
0

There's no need to 'obtain a reference' to BroadcastReceiver which is already registered.

Just send Intent which can be handled by that BroadcastReceiver to trigger its action from any point of the code where you have a Context.

context.sendBroadcast(intent);

If you want to call 'pure logic' without calling BroadcastReceiver you have to extract logic from it to some POJO class and call that class directly omitting BroadcastReceiver.

class LocationReceiver extends BroadcastReceiver {

       private SomeAction action;

       public LocationReceiver(){
           action = new SomeAction();
       }

        @Override
        public void onReceive(Context context, Intent intent) {
            action.execute();
        }
    };

BroadcastReceiver can simply call execute() but it doesn't know anything about how it works. You can reuse SomeAction anywhere in your code without having a knowledge about BroadcastReceiver at all.

Try to avoid putting a logic inside Android classes.

It's better to have logic in POJO Java classes because it helps to keep SRP principle alive and makes testing easier.

klimat
  • 24,711
  • 7
  • 63
  • 70
  • thank you but i don't think that i understood my issue, i probably didn't give enough details. I edited my post so it's a little bit more clear. I have no problem with sending a broadcast / executing some action. – Jakub Holovsky Jul 18 '16 at 09:43
  • If you extract `SomeAction` outside `BroadcastReceiver` you will be able to subscribe to `SomeAction` instead a receiver. Even more you will be able to write unit test to it :) – klimat Jul 18 '16 at 09:45
  • I see what you mean. Yeah, sounds like a solution. I meant more like putting public event Action OnMyAction; into my BR, obtaining a reference to my BR and then subscribing to that event. – Jakub Holovsky Jul 18 '16 at 09:55