-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Move inject before onCreate for Activity #598
Comments
Thank you, @bubenheimer! I've tried to integrate the compiled artifacts from your repo and it works like a charm even with Kotlin. In fact, this is the only workable solution I've found so far which makes it possible to play with the new Android Injection feature. |
In the meantime I've looked at the behavior when using framework Activity & Fragment classes instead of support classes, and the problem & fix are the same, on API level 24. I've added the code changes for this test to the "framework" branch of my Github example. Also, to whoever decided to use my custom-built Dagger artifacts, consider grabbing the latest - I've refreshed the Android-related artifacts, and I noticed that I previously may have accidentally incorporated my suggested code change in the dagger-android artifact already (in DaggerActivity.class). |
Hm, I thought I responded to this but maybe not. I'm going to investigate this, and I hope to have an answer soon, but I have a few things on my plate right now. I regretfully should have tested configuration changes :( |
Any issue with doing the fragment injection within onActivityCreated? |
I'd commonly want to access Dagger-injected values before onActivityCreated. You'd be skipping three major lifecycle methods. |
Yes, ideally we want to trigger members injection as close to object construction as possible. We don't suspect that there should be any issue with doing it before |
I suppose the general concern should be one of minimizing problems for the default approach. There can be issues whichever order & timing we choose. I ran into problems in the past with doing injection before onCreate(), I guess because I was using aspects of the Activity class during injection that were waiting to be initialized via onCreate(). However, that's an issue tied to my own code structure that is more readily identified and resolved than standard framework problems. That said I am more hesitant now to advocate placing Fragment injection before super.onAttach(), unless it solves a specific problem apart from consistency/confusion. In my own code I have generally had Fragments inject themselves after super.onAttach(). More recently I avoided self-injection for Fragments and Views entirely, by using Activity.onCreateView(), Activity.onAttachFragment, and Fragment.onAttachFragment for child fragments. |
Fragments are attached in super.onCreate(), where they get injected, and therefore need the activity to have already been injected. Fixes #598 This is enforced by error-prone in [] ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=149038239
Fragments are attached in super.onCreate(), where they get injected, and therefore need the activity to have already been injected. Fixes #598 ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=149038239
Fragments are attached in super.onCreate(), where they get injected, and therefore need the activity to have already been injected. Fixes #598 This is enforced by error-prone in [] ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=149038239
Fragments are attached in super.onCreate(), where they get injected, and therefore need the activity to have already been injected. Fixes #598 This is enforced by error-prone in [] ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=149038239
Since you added AndroidInjectionBeforeSuper errorprone bug pattern the projects cannot be compiled now if the For example, consider RxPermissions injection. It uses the fragment transactions under the hood. Therefore, the exception I know that it is possible to suppress the errorprone by |
@storix I'm not following what is happening in RxPermissions. Can you explain a bit more? |
AFAICT, RxPermissions' “constructor does real work” and specifically uses the @storix How about injecting a |
@ronshapiro It uses the retained fragment to save/restore some important properties on configuration changes. When the activity is recreated it retrieves the fragment upon its object creation to restore the required fields so we can resubscribe to the permissions notifications right away. Actually, you don't even need to analyze all the logic behind RxPermissions. You can just try to use the fragment manager in any activity like this:
@tbroyer Yes, injecting a Idk, maybe some warning should be added to the docs regarding such situations. |
Why are you injecting the |
I'm injecting it into the constructor of the presenter which manages all permissions related logic. |
DaggerAppCompatActivity.onCreate() currently looks like this:
This causes a NullPointerException when a Fragment is added via the support FragmentManager and a configuration change occurs (e.g. screen rotation), and the Fragment is restored by the framework. The problem is that Fragment.onAttach() is then called within the Activity's onCreate(), where fields are not yet injected, but needed to inject the Fragment.
Instead, the order of the two statements needs to be flipped - injection needs to happen before super.onCreate().
I've created a sample app to demonstrate the issue: https://github.com/bubenheimer/daggerinitorderbug
The sample app uses my own builds of the Dagger artifacts, to work around other issues with RC1.
I don't know the behavior with framework Activities, as opposed to AppCompatActivities. I'd think it should be treated the same, at least to be consistent, but have not tested it.
I don't have a strong opinion on the order for DaggerFragment - the equivalent problem does not occur for support child Fragments (children of a parent Fragment) - also shown in my sample app. Injecting after 'super.onAttach()' works fine in all of my production code, too, but perhaps it would be better to flip the order to be consistent.
Seeing this issue in the code was what led me to spend my time on evaluating the RC, to get it changed before reaching release. Thanks for providing an RC!
The text was updated successfully, but these errors were encountered: