3

I have an activity in which I have a broadcast receiver (br). If I register the br programmatically the receiver is registered and works great.

However, if I register the receiver in the manifest I receive a java.lang.ClassNotFoundException.

<receiver             
        android:name=".MyActivity.UpdateUIClass"
        android:exported="false"
        >
        <intent-filter>
            <action android:name="com.mydomain.main.FILTER_UPDATE_UI" />
            <category android:name="android.intent.category.DEFAULT" />                
        </intent-filter>
    </receiver>

Please advise

Roy Hinkley
  • 10,111
  • 21
  • 80
  • 120

1 Answers1

6

If UpdateUIClass is an internal class of MyActivity then you need to refer to it this way android:name=".MyActivity$UpdateUIClass"

This is the way you do it in a layout XML. Not sure if this will work for the manifest but give it a go and see if it works.

Edit

This is not possible unless the inner class is static as the manifest marshals all objects at load and not on demand. The class hosting the sub-class does not exist at the time the receiver is being resolved.

Related question: Is it possible to define a broadcast receiver as an inner class in manifest file?

Community
  • 1
  • 1
Michael Celey
  • 12,645
  • 6
  • 57
  • 62
  • Well, it sees it now (don't get class not found exception), but now I get "Unable to instantiate receiver ..." no empty constructor - added one and still get error. – Roy Hinkley Sep 21 '12 at 18:05
  • Make sure the internal class and the constructor are both public. – Michael Celey Sep 21 '12 at 18:09
  • Curious why registering programmatically versus manifest is different. Are things marshalled differently? – Roy Hinkley Sep 21 '12 at 18:11
  • Just tried static - won't work. None of my methods are accessible then. I will go with status-quo and register them with code, but would prefer to do so via manifest - less housekeeping to deal with. – Roy Hinkley Sep 21 '12 at 18:12
  • Sorry about the static comment, I edited the comment immediately after posting it because it was a bad idea. Check what the comment was updated to. – Michael Celey Sep 21 '12 at 18:27
  • Yes, both are public - always have been. – Roy Hinkley Sep 21 '12 at 18:41
  • Then I'll have to go back to my suggestion of making the class static or splitting it into another file. The downside to that, as you saw, is that it can no longer access the Activity class in the same way so you'd have to make some larger code changes. The only reason I can see as to why it can't instantiate the receiver is that it needs a reference to the external class to get to the internal class. By making the receiver class static or splitting it into a separate file, you'd eliminate that limitation. The reason it's easier through code is that you're creating the reference yourself. – Michael Celey Sep 21 '12 at 19:31
  • Thanks for the suggestion but as stated earlier, I will register with code. Refactoring all that would be affected is not an option. I would really like to know if this is a bug or what. I just want to understand what's going on here. – Roy Hinkley Sep 21 '12 at 19:34
  • It's not a bug, it's just how Java deals with accessing internal classes. If you can't make an instance of the outer class then you can't get to a dependent internal class. The reason you can do it in code is that you're creating the internal class instance from inside the external class. You already have an instance of the class that the system can't create on its own. – Michael Celey Sep 21 '12 at 19:42
  • Thank you for the explanation - it makes sense now. I am assuming that the marshalling of the class from the manifest happens when the apk is loaded and not on demand. For completeness, the activity is declared in the manifest above the receiver declaration. – Roy Hinkley Sep 21 '12 at 19:53