Screen rotation with fragments

2,832 views
Skip to first unread message

Manfred Moser

unread,
Nov 29, 2011, 2:45:42 PM11/29/11
to robo...@googlegroups.com
Hi!

In my app I seem to be getting issues with injecting views when rotating the screen. I have a frame that I am dynamically inserting the fragments with a transaction. 

Doing something like this

   SplashScreenFragment fragment = new SplashScreenFragment();
            getSupportFragmentManager().beginTransaction().replace(R.id.frameMain, fragment).commit();

On rotation I get strack traces like this although the same view comes up fine before the rotation and if I restart the app it also works in the new rotation. It seems that the rotation itself and the state change there is causing it and somehow injection does not happen during rotation.

Anybody got a clue where to look?

        java.lang.RuntimeException: Unable to start activity ComponentInfo{com.somewhere.mobile/com.somwhere.mobile.activity.RootFragmentActivity}: java.lang.NullPointerException: Can't inject null value into class com.somewhere.mobile.fragment.CategoryTaxonomyFragment.btnRoot when field is not @Nullable
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1748)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1764)
        at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3114)
        at android.app.ActivityThread.access$1600(ActivityThread.java:122)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1006)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:132)
        at android.app.ActivityThread.main(ActivityThread.java:4025)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:491)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:841)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:599)
        at dalvik.system.NativeStart.main(Native Method)
        Caused by: java.lang.NullPointerException: Can't inject null value into class com.somewhere.mobile.fragment.CategoryTaxonomyFragment.btnRoot when field is not @Nullable
        at roboguice.inject.ViewListener$ViewMembersInjector.reallyInjectMemberViews(ViewListener.java:153)
        at roboguice.inject.ViewListener$ViewMembersInjector.reallyInjectMembers(ViewListener.java:127)
        at roboguice.inject.ViewListener$ViewMembersInjector.injectViews(ViewListener.java:209)
        at roboguice.inject.ContextScopedRoboInjector.injectViewMembers(ContextScopedRoboInjector.java:258)
        at roboguice.activity.RoboFragmentActivity.onContentChanged(RoboFragmentActivity.java:107)
        at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:226)
        at android.app.Activity.setContentView(Activity.java:1780)
        at com.somewhere.mobile.activity.RootFragmentActivity.onCreate(RootFragmentActivity.java:46)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1048)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1712)
        ... 12 more

Donn Felker

unread,
Nov 29, 2011, 3:03:36 PM11/29/11
to robo...@googlegroups.com
I also get this same error. After adding the Nullable on the field everything seemed to load ok. However, please do not take this as a solution as my fragment is still in development at this time. But I'm with you, I'm having the same issue on rotation. 

Donn


--
You received this message because you are subscribed to the Google Groups "roboguice" group.
To view this discussion on the web visit https://groups.google.com/d/msg/roboguice/-/Jqjc7uwqkjEJ.
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.

Manfred Moser

unread,
Nov 29, 2011, 3:13:56 PM11/29/11
to robo...@googlegroups.com
But if I add nullable and the view then are null I will get NPE's all over the place later right?

Michael Burton

unread,
Nov 29, 2011, 3:34:39 PM11/29/11
to robo...@googlegroups.com
Possibly related, although hard to say: http://stackoverflow.com/questions/8289660/any-simple-examples-using-roboguice-with-fragments-in-android

Seems like there may be an issue with injection in fragments that will require more investigation.  Donn's workaround using Nullable may work, although it's not clear to me why it's necessary nor why it doesn't result in NPEs further down the line.

Manfred Moser

unread,
Nov 29, 2011, 3:41:32 PM11/29/11
to robo...@googlegroups.com
Makes me think we should have a sample app with fragments. Should we pull christine's sample in to work on it together or so?

Michael Burton

unread,
Nov 29, 2011, 3:45:10 PM11/29/11
to robo...@googlegroups.com
Gosh, I wish there was some service out there that made it easy for people to submit contributions.  Maybe some cool website that tied allowed submission of changesets.  We could call them Pull Requests.  We could make a FORTUNE.

Mike

PS. Stay tuned for news on this front.  Don't hold your breath, it's not going to be immediate, but I've caved and am planning on moving to git "soon-ish".

Manfred Moser

unread,
Nov 29, 2011, 3:48:06 PM11/29/11
to robo...@googlegroups.com
AWESOME! 

Macarse

unread,
Nov 29, 2011, 3:52:19 PM11/29/11
to robo...@googlegroups.com

Donn Felker

unread,
Nov 29, 2011, 4:04:21 PM11/29/11
to robo...@googlegroups.com
Git. :)

Manfred Moser

unread,
Nov 29, 2011, 5:23:06 PM11/29/11
to robo...@googlegroups.com
From first testing the @Nullable workaround fails for me.. need to check more though.

Donn Felker

unread,
Dec 4, 2011, 3:53:12 PM12/4/11
to robo...@googlegroups.com
Manfred - I'm also having issues with another project where injection is failing on an activity and giving me the @Nulable error as well. Not sure what's causing it 

Manfred Moser

unread,
Dec 5, 2011, 11:50:28 AM12/5/11
to robo...@googlegroups.com
I have not had time to look at it further yet but we are going to have to suss this out prior to the 2.0 release.. 

manfred

On Sun, Dec 4, 2011 at 12:53 PM, Donn Felker <dfe...@gmail.com> wrote:
Manfred - I'm also having issues with another project where injection is failing on an activity and giving me the @Nulable error as well. Not sure what's causing it 

--
You received this message because you are subscribed to the Google Groups "roboguice" group.
To view this discussion on the web visit https://groups.google.com/d/msg/roboguice/-/4f0-MDtaLPgJ.

Michael Burton

unread,
Dec 5, 2011, 11:51:27 AM12/5/11
to robo...@googlegroups.com

Christine

unread,
Dec 6, 2011, 7:12:16 PM12/6/11
to roboguice
Does this happen in honeycomb also, or only if you use the support
package? I don't have a lot of time currently, but I'm willing to
help.

> com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.jav a:226)
>         at android.app.Activity.setContentView(Activity.java:1780)
>         at
> com.somewhere.mobile.activity.RootFragmentActivity.onCreate(RootFragmentAct ivity.java:46)

Manfred Moser

unread,
Dec 7, 2011, 12:43:56 PM12/7/11
to robo...@googlegroups.com
I am using the support package with the app running on a honeycomb tablet. On the non honeycomb devices there are different mechanics in my case so that problem does not appear. I do not dynamically insert fragments into layouts on the smaller device. 

That said I am going to try and run it on a emulator of tablet size with pre honeycomb sdk and report back.

manfred

--
You received this message because you are subscribed to the Google Groups "roboguice" group.

Manfred Moser

unread,
Dec 7, 2011, 1:12:08 PM12/7/11
to robo...@googlegroups.com
Okay.. same problem with the app running on a 2.3.3 tablet size device using the fragment stuff. So whatever it is .. it has to do with how we inject stuff when a fragment is hauled up. 

One thing to think about maybe is that I replace fragments in the layout with a transaction in which I do a 

new XYZFragment()

.. maybe I have to replace that with creating it from the injector .. but then why does it work at initial start before the rotation.

hm..

manfred

Cherry Development

unread,
Dec 9, 2011, 6:29:10 PM12/9/11
to roboguice
I might have a solution to this problem, but I don't know enough about
the internals of RoboGuice to know if there's a reason why this
solution won't work.

When the screen is rotated and a Fragment was added to the previous
instance of the Activity, the new Activity gets that Fragment attached
to it automatically when it's being created.
ViewMembersInjector.injectMembers then adds the injectable members of
the Fragment directly to the Activity (in the first half of the
method) and then adds the injectable members again to the Fragment in
the second half of the method. If setContentView is then called from
the Activity's onCreate, onContentChanged ends up being called before
the Fragment has had onCreateView called on it. The Fragment's view
is not created, and therefore we get a crash when the its views are
injected. What I'm uncertain of is WHY the Fragments' members are
being attached to the Activity at all. Is this to support Fragments
that have @InjectView annotations but are NOT RoboFragments?

As a temporary work-around, I created a new marker interface
InjectsOwnViews and had all of the Robo versions of the Fragment
classes (RoboFragment, RoboListFragment, RoboDialogFragment) implement
it. When ViewMembersInjector.injectMembers is then called, it ignores
any fragments that implement InjectsOwnViews. The Fragment's view
injection is then delayed until after its onCreateView method is
called, as we would expect.

What I can't figure out is why this makes a difference if the Fragment
was attached to the Activity's view hierarchy directly (non-
programmatically) or when it's later attached programmatically. The
approach that I tried appears to work for both cases. It's possible
that the first half of the ViewMembersInjector method was NEVER
intended to be used on Fragments at all. Can anybody who understands
this better let us know? If this is the case, the solution to this
problem is literally a single line. Just wrap the first half of
ViewMembersInjector.injectMembers with

if ( ! (instance instanceof Fragment) ) {
...

Manfred Moser

unread,
Dec 9, 2011, 6:49:31 PM12/9/11
to robo...@googlegroups.com
Thats sounds awesome. I will try that next week..

Manfred Moser

unread,
Dec 9, 2011, 7:29:47 PM12/9/11
to robo...@googlegroups.com
I could not wait ... I tried this and it does seem to prevent the crash from happening. However somehow it seems to forget the last fragment that was there as well and get back to the initial view.. but that might be a problem with my app..

So I would say we should pull this in and take a closer look with it.

manfred

Cherry Development

unread,
Dec 9, 2011, 7:38:53 PM12/9/11
to robo...@googlegroups.com
The following behaviour seems to be working for me:

RoboFragmentActivity that starts with no fragments attached.
A button attaches a RoboFragment that's added to the back stack.
A button on the fragment pops up a RoboDialogFragment.

Rotate the screen:

All elements are the way they're supposed to be.

Michael Burton

unread,
Dec 10, 2011, 2:32:30 PM12/10/11
to robo...@googlegroups.com
I'm trying to follow along on this thread, but I don't have an example that reproduces the problem.  Does anyone think they can supply a small project or testcase that demonstrates the problem?

--
You received this message because you are subscribed to the Google Groups "roboguice" group.
To view this discussion on the web visit https://groups.google.com/d/msg/roboguice/-/R4Floj2y9ygJ.

Michael Burton

unread,
Dec 11, 2011, 10:04:32 AM12/11/11
to robo...@googlegroups.com
Ah, never mind.  I was able to repro the issue by modifying Astroboy to follow Cherry Development's steps outline below.

Here's the project that will crash on screen rotation after you click the two buttons

Michael Burton

unread,
Dec 11, 2011, 10:21:33 AM12/11/11
to robo...@googlegroups.com
Cherry, I'm wondering whether my example below is exposing the same issue that you're seeing.  Here's the crash I get, is this the same one you're seeing?

11-01 06:50:21.575 E/AndroidRuntime( 4119): java.lang.RuntimeException: Unable to start activity ComponentInfo{org.roboguice.astroboy/org.roboguice.astroboy.activity.AstroFragmentActivity}: android.support.v4.app.Fragment$InstantiationException: Unable to instantiate fragment org.roboguice.astroboy.fragment.Fragment1$1$1: make sure class name exists, is public, and has an empty constructor that is public
11-01 06:50:21.575 E/AndroidRuntime( 4119): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1647)
11-01 06:50:21.575 E/AndroidRuntime( 4119): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1663)
11-01 06:50:21.575 E/AndroidRuntime( 4119): at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:2832)
11-01 06:50:21.575 E/AndroidRuntime( 4119): at android.app.ActivityThread.access$1600(ActivityThread.java:117)
11-01 06:50:21.575 E/AndroidRuntime( 4119): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:935)
11-01 06:50:21.575 E/AndroidRuntime( 4119): at android.os.Handler.dispatchMessage(Handler.java:99)
11-01 06:50:21.575 E/AndroidRuntime( 4119): at android.os.Looper.loop(Looper.java:130)
11-01 06:50:21.575 E/AndroidRuntime( 4119): at android.app.ActivityThread.main(ActivityThread.java:3683)
11-01 06:50:21.575 E/AndroidRuntime( 4119): at java.lang.reflect.Method.invokeNative(Native Method)
11-01 06:50:21.575 E/AndroidRuntime( 4119): at java.lang.reflect.Method.invoke(Method.java:507)
11-01 06:50:21.575 E/AndroidRuntime( 4119): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
11-01 06:50:21.575 E/AndroidRuntime( 4119): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
11-01 06:50:21.575 E/AndroidRuntime( 4119): at dalvik.system.NativeStart.main(Native Method)
11-01 06:50:21.575 E/AndroidRuntime( 4119): Caused by: android.support.v4.app.Fragment$InstantiationException: Unable to instantiate fragment org.roboguice.astroboy.fragment.Fragment1$1$1: make sure class name exists, is public, and has an empty constructor that is public
11-01 06:50:21.575 E/AndroidRuntime( 4119): at android.support.v4.app.Fragment.instantiate(Fragment.java:388)
11-01 06:50:21.575 E/AndroidRuntime( 4119): at android.support.v4.app.FragmentState.instantiate(Fragment.java:96)
11-01 06:50:21.575 E/AndroidRuntime( 4119): at android.support.v4.app.FragmentManagerImpl.restoreAllState(FragmentManager.java:1662)
11-01 06:50:21.575 E/AndroidRuntime( 4119): at android.support.v4.app.FragmentActivity.onCreate(FragmentActivity.java:192)
11-01 06:50:21.575 E/AndroidRuntime( 4119): at roboguice.activity.RoboFragmentActivity.onCreate(RoboFragmentActivity.java:41)
11-01 06:50:21.575 E/AndroidRuntime( 4119): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
11-01 06:50:21.575 E/AndroidRuntime( 4119): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1611)
11-01 06:50:21.575 E/AndroidRuntime( 4119): ... 12 more
11-01 06:50:21.575 E/AndroidRuntime( 4119): Caused by: java.lang.InstantiationException: org.roboguice.astroboy.fragment.Fragment1$1$1
11-01 06:50:21.575 E/AndroidRuntime( 4119): at java.lang.Class.newInstanceImpl(Native Method)
11-01 06:50:21.575 E/AndroidRuntime( 4119): at java.lang.Class.newInstance(Class.java:1409)
11-01 06:50:21.575 E/AndroidRuntime( 4119): at android.support.v4.app.Fragment.instantiate(Fragment.java:377)
11-01 06:50:21.575 E/AndroidRuntime( 4119): ... 18 more

daniel

unread,
Dec 11, 2011, 3:56:22 PM12/11/11
to roboguice
I have created a small testcase that always crash with

"NullPointerException: Can't inject null value into class
com.foo.bar.fragmentrotation.HelloAndroidFragment.hello when field is
not @Nullable"
The integration test does not always catch the error, but the
application will always crash when you try to change the orientation.

http://dl.dropbox.com/u/4723421/fragmentrotation.zip

I hope this is the same case reported first in this thread.

On 11 Des, 16:21, Michael Burton <m...@niskala.org> wrote:
> Cherry, I'm wondering whether my example below is exposing the same issue that you're seeing.  Here's the crash I get, is this the same one you're seeing?
>

> 11-01 06:50:21.575 E/AndroidRuntime( 4119): java.lang.RuntimeException: Unable to start activity ComponentInfo{org.roboguice.astroboy/org.roboguice.astroboy.activity.AstroF ragmentActivity}: android.support.v4.app.Fragment$InstantiationException: Unable to instantiate fragment org.roboguice.astroboy.fragment.Fragment1$1$1: make sure class name exists, is public, and has an empty constructor that is public


> 11-01 06:50:21.575 E/AndroidRuntime( 4119):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1647)
> 11-01 06:50:21.575 E/AndroidRuntime( 4119):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1663)
> 11-01 06:50:21.575 E/AndroidRuntime( 4119):     at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:2832)
> 11-01 06:50:21.575 E/AndroidRuntime( 4119):     at android.app.ActivityThread.access$1600(ActivityThread.java:117)
> 11-01 06:50:21.575 E/AndroidRuntime( 4119):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:935)
> 11-01 06:50:21.575 E/AndroidRuntime( 4119):     at android.os.Handler.dispatchMessage(Handler.java:99)
> 11-01 06:50:21.575 E/AndroidRuntime( 4119):     at android.os.Looper.loop(Looper.java:130)
> 11-01 06:50:21.575 E/AndroidRuntime( 4119):     at android.app.ActivityThread.main(ActivityThread.java:3683)
> 11-01 06:50:21.575 E/AndroidRuntime( 4119):     at java.lang.reflect.Method.invokeNative(Native Method)
> 11-01 06:50:21.575 E/AndroidRuntime( 4119):     at java.lang.reflect.Method.invoke(Method.java:507)
> 11-01 06:50:21.575 E/AndroidRuntime( 4119):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java: 839)
> 11-01 06:50:21.575 E/AndroidRuntime( 4119):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
> 11-01 06:50:21.575 E/AndroidRuntime( 4119):     at dalvik.system.NativeStart.main(Native Method)
> 11-01 06:50:21.575 E/AndroidRuntime( 4119): Caused by: android.support.v4.app.Fragment$InstantiationException: Unable to instantiate fragment org.roboguice.astroboy.fragment.Fragment1$1$1: make sure class name exists, is public, and has an empty constructor that is public
> 11-01 06:50:21.575 E/AndroidRuntime( 4119):     at android.support.v4.app.Fragment.instantiate(Fragment.java:388)
> 11-01 06:50:21.575 E/AndroidRuntime( 4119):     at android.support.v4.app.FragmentState.instantiate(Fragment.java:96)

> 11-01 06:50:21.575 E/AndroidRuntime( 4119):     at android.support.v4.app.FragmentManagerImpl.restoreAllState(FragmentManager. java:1662)


> 11-01 06:50:21.575 E/AndroidRuntime( 4119):     at android.support.v4.app.FragmentActivity.onCreate(FragmentActivity.java:192)
> 11-01 06:50:21.575 E/AndroidRuntime( 4119):     at roboguice.activity.RoboFragmentActivity.onCreate(RoboFragmentActivity.java: 41)
> 11-01 06:50:21.575 E/AndroidRuntime( 4119):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
> 11-01 06:50:21.575 E/AndroidRuntime( 4119):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1611)
> 11-01 06:50:21.575 E/AndroidRuntime( 4119):     ... 12 more
> 11-01 06:50:21.575 E/AndroidRuntime( 4119): Caused by: java.lang.InstantiationException: org.roboguice.astroboy.fragment.Fragment1$1$1
> 11-01 06:50:21.575 E/AndroidRuntime( 4119):     at java.lang.Class.newInstanceImpl(Native Method)
> 11-01 06:50:21.575 E/AndroidRuntime( 4119):     at java.lang.Class.newInstance(Class.java:1409)
> 11-01 06:50:21.575 E/AndroidRuntime( 4119):     at android.support.v4.app.Fragment.instantiate(Fragment.java:377)
> 11-01 06:50:21.575 E/AndroidRuntime( 4119):     ... 18 more
>

> --http://about.me/michaelburton


>
> On Dec 11, 2011, at 12:04 PM, Michael Burton wrote:
>
>
>
>
>
>
>
> > Ah, never mind.  I was able to repro the issue by modifying Astroboy to follow Cherry Development's steps outline below.
>
> > Here's the project that will crash on screen rotation after you click the two buttons
>
> >http://cl.ly/10293J2f1e1b1p3r2t33
>
> > Mike
>
> > --
> >http://about.me/michaelburton
>
> > On Dec 10, 2011, at 4:32 PM, Michael Burton wrote:
>
> >> I'm trying to follow along on this thread, but I don't have an example that reproduces the problem.  Does anyone think they can supply a small project or testcase that demonstrates the problem?
>
> >> --
> >>http://about.me/michaelburton
>
> >> On Dec 9, 2011, at 9:38 PM, Cherry Development wrote:
>
> >>> The following behaviour seems to be working for me:
>
> >>> RoboFragmentActivity that starts with no fragments attached.
> >>> A button attaches a RoboFragment that's added to the back stack.
> >>> A button on the fragment pops up a RoboDialogFragment.
>
> >>> Rotate the screen:
>
> >>> All elements are the way they're supposed to be.
>
> >>> --
> >>> You received this message because you are subscribed to the Google Groups "roboguice" group.

> >>> To view this discussion on the web visithttps://groups.google.com/d/msg/roboguice/-/R4Floj2y9ygJ.

Cherry Development

unread,
Dec 11, 2011, 4:40:21 PM12/11/11
to robo...@googlegroups.com
Michael,

That error is caused by the fact that when the Android is re-creating an activity that has fragments attached to it, it will re-attach the fragments automatically.  In order to do that, though, it has to re-instantiate new Fragments.  It does this simply by calling new Foo() on the Fragment class.  I'm pretty sure that your Fragment class should be a static class, if it's inner, and it must have a default constructor.

If you need to do some initialization of your Fragment from a parent component, you can get findFragment() from the parent fragment/activity and set it up there.  If the fragment has internal state that can be saved in a Bundle, it should just do that in onSaveInstanceState and restore it on onCreate or onActivityCreated().  It will do this automatically, anyway for any views inside of your Fragment.  If you need to set callbacks, though, you won't be able to persist your callbacks in onSaveInstanceState, of course, and you'll need to set them back up manually.

Make sense?

Manfred Moser

unread,
Dec 12, 2011, 12:42:17 PM12/12/11
to robo...@googlegroups.com
Hi CherryDev,

The demo app you posted is showing the same problem I originally experienced. When I apply your suggested fix to the roboguice version locally it works. 

So at this stage I would suggest that Michael pulls that in. Maybe you could provide it as a patch (or pull request as soon as Mike has migrated to github .. )

I also think your example would be a good addition to the astroboy example with some tweaks that we can do once it is all in github.. (e.g. it is not full screen on a tablet..) 

I will for now use the patched version I have locally and see how I can fix my other issues.

manfred

Manfred Moser

unread,
Dec 12, 2011, 1:51:37 PM12/12/11
to robo...@googlegroups.com
Okay... I sussed out my other problems so it is all working like a charm. No I just gotta make sure that all my fragments persist state across rotation nicely.

manfred

Michael Burton

unread,
Dec 19, 2011, 6:46:06 PM12/19/11
to robo...@googlegroups.com
Okay, I see the problem.  Filed as http://code.google.com/p/roboguice/issues/detail?id=166  Fixed, the latest snapshot should resolve the issue for the code that daniel posted.

Basically, we can inject views into 3 different type of classes.

  1. Activity subclasses
  2. Fragment subclasses
  3. Everything else (POJOs)

Injecting into #1 and #2 is obvious.  Injecting into #3 is not as clear.  Prior to fragment support in RoboGuice, it was obvious that the place to find a view for a POJO was from the current activity.  However, now that fragments can also have views, that's no longer always the case.

The way I was handling this in ViewListener.ViewMembersInjector.injectMembers was as follows:

        public void injectMembers(T instance) {
                ...

                // SECTION A
                // Add a view injector for the activity
                ArrayList<ViewMembersInjector<?>> injectors = viewMembersInjectors.get(activity);
                ...
                injectors.add(this);


                // SECTION B
                // Add a view injector for the fragment, if appropriate
                if( fragmentClass!=null && fragmentClass.isInstance(instance) ) {
                    injectors = viewMembersInjectors.get(instance);
                    ...
                    injectors.add(this);
                }

                ...

        }


If this is an activity or a pojo, SECTION A would be executed.  If a fragment, SECTION B would be executed.  The code is obviously wrong though, because for a fragment section A would ALSO get executed, resulting in an extra ViewMembersInjector for the fragment getting added to the list, only for the Activity.

This is why we're seeing the crash.  Because after a screen rotation, Activity.onCreate is called, which results in this extra ViewMembersInjector getting called, at which point we try to erroneously inject the fragment's view into the activity, and at that point the view is null.

So why is this only happening on rotation and not every time the activity starts?  Because the activity's onContentViewChanged is being called before we attempt to do any injection into any fragments.  This means that the at the time we try to inject the view members the first time, we haven't yet erroneously inserted any invalid ViewMembersInjectors yet, so there's no crash.

The fix is to make SECTION A conditional so that it only gets executed if SECTION B doesn't get executed.[1]  I've added a testcase for the issue as well.  

Mike

[1] There's an implication to this, which is that it means that you can't inject Fragment views into POJOs at this time.  You couldn't before the fix so nothing is different, but this change makes that more clear.  A proper fix further down the line would be to introduce Fragment Scoping (just like we have ContextScoping) so that we can associate a given POJO with a given fragment, just like we already can with contexts.  Once we have that, then we should be able to inject fragment views into POJOs.  However, that's a change that will require a bit of thought, so I think I may want to hold off on that for the initial 2.0 release.
--
http://about.me/michaelburton





Manfred Moser

unread,
Dec 19, 2011, 6:52:32 PM12/19/11
to robo...@googlegroups.com
Thanks for the new snapshot. Works great so far for me. Btw.. what about that migration to github ;-)

manfred

Michael Burton

unread,
Dec 19, 2011, 7:00:08 PM12/19/11
to robo...@googlegroups.com
If I don't get on to github within a month or so after 2.0 is released, i'm buying you all a beer.

Manfred Moser

unread,
Dec 19, 2011, 7:11:58 PM12/19/11
to robo...@googlegroups.com
I guess the 2.1. release will have lots of contributions then ;-)

manfred

Donn Felker

unread,
Dec 19, 2011, 11:10:38 PM12/19/11
to robo...@googlegroups.com
git remote add origin <path to github repo>
git init
git add . 
git commit -am "Initial git commit" 
git push origin master

Manfred Moser

unread,
Dec 19, 2011, 11:38:04 PM12/19/11
to robo...@googlegroups.com
welll on the surface yes.. put practically that looses history and does not update the release process.. so there is more involved.. 

manfred

--
You received this message because you are subscribed to the Google Groups "roboguice" group.
To view this discussion on the web visit https://groups.google.com/d/msg/roboguice/-/3g-Aq0hxIXcJ.

Donn Felker

unread,
Dec 19, 2011, 11:42:46 PM12/19/11
to robo...@googlegroups.com

Of course, Manfred... always gotta be a party pooper ... :)

Sent via Android

Manfred Moser

unread,
Dec 20, 2011, 1:11:26 AM12/20/11
to robo...@googlegroups.com
hahah.. seriously.. I had a bit of a look around. Supposedly the hg git integration available at

should be easy to do the whole import with. Then it is just a question of updating the pom for the release process with these tips


and you should be rocking..

How about doing that as xmas pressie for us for the 2.0 release Mike ;-) 

manfred

daniel

unread,
Dec 20, 2011, 4:51:13 AM12/20/11
to roboguice
The bugfix is working great in my application too. Thanx!

On 20 Des, 00:46, Michael Burton <m...@niskala.org> wrote:
> Okay, I see the problem.  Filed ashttp://code.google.com/p/roboguice/issues/detail?id=166 Fixed, the latest snapshot should resolve the issue for the code that daniel posted.

Michael Burton

unread,
Feb 23, 2012, 7:09:04 PM2/23/12
to robo...@googlegroups.com
I'm going to do a bug pass here relatively soon.  Can you file a bug if there isn't one already?

Cheers,
Mike

On Feb 22, 2012, at 11:29 PM, Logdog82 wrote:

Hi there,

I've got the same issue. With RoboGuice 2.0 Beta 3 I've got the Exception "java.lang.NullPointerException: Can't inject null value into class foo.bar.fragment.Myragment.buttonTest when field is not @Nullable"
Now I've upgraded to the latest Snapshot. The Exception is gone. Fine. But if I change the orientation all my private injected fields (via @InjectView) are now null. This only happens on screen orientation change. Before I change the orientation all private fields are injected fine.
Any ideas?

--
You received this message because you are subscribed to the Google Groups "roboguice" group.
To view this discussion on the web visit https://groups.google.com/d/msg/roboguice/-/_pqvvWpn1_sJ.

Donn Felker

unread,
Feb 29, 2012, 10:05:46 AM2/29/12
to robo...@googlegroups.com
Thanks for the bug report and sample code. 

:)


On Wed, Feb 29, 2012 at 7:04 AM, Christian Rackerseder <chri...@echooff.de> wrote:
Done. Issue 183 (http://code.google.com/p/roboguice/issues/detail?id=183)

2012/2/24 Michael Burton <mi...@niskala.org>:
Reply all
Reply to author
Forward
Message has been deleted
Message has been deleted
Message has been deleted
0 new messages