-
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
@AndroidEntryPoint-annotated classes cannot have type parameters. #3370
Comments
The solution is to put the // Put the annotation here instead of on the base class.
@AndroidEntryPoint
class MyFragment: BaseFragment<MyViewModel, MyViewDataBinding>() {
...
} See #2042 (comment) |
I have tried this solution was still have problems. |
Do you have more details (e.g. error message or stack trace)? |
This solves the compile error for me. But if I remove It's a valid cases where both base class and child class have injected fields. |
@Archerkills All of the However, if you can provide a sample project where this isn't working for you I'm happy to take a look. |
@bcorso thanks for a quick response, I am working on WhatsApp Android code base and I will forward your response to our internal DI dicussion. |
@bcorso the problem turns out to be that we have a lot of logic to access injected params in base View's constructor to init view state. But Hilt_BaseView's constructor calls inject() AFTER super(), causing NPE.
Note that is was not a problem before we added generic types and remove |
Unfortunately, Java requires the TBH, we haven't hit this use case yet, so I'll have to talk to the team to see how we want to officially support it. If possible, it would be great to try to avoid doing work in your view's constructor, but I do agree that this is unfortunate since normally this approach works within the constructor of an One (pretty bad) workaround is to define an abstract abstract class MiddleView<T extends E> extends BaseView<T> {
@Inject Foo foo;
MiddleView(Context context, ...) {
super(context, ...);
inject(); // <-- Call injection manually here before using foo
this.foo.callSomeMethod();
}
// This is a hack to allow injection early in the base class constructor without using @AndroidEntryPoint.
// This method will be implemented by Hilt's generated class.
protected abstract void inject();
} Note that this works because the Hilt generated code will generate the implementation of the However, the reason this is a "bad" approach is because it relies on an implementation detail of Hilt's generated code. In particular, the |
@bcorso Adding |
Is this from profiling your app? If so, can you share the profile? Usually the latency is either coming from creating all of the objects needed to inject your view (and their transitive dependencies), or from doing extraneous work in your constructor (e.g. |
You are right. It's from CPU profiling our app. I am not sure if I am allowed to share our CPU profile before I consulted our leadership. But I looked into some of the big Back to
Can you confirm those 2 assumptions are correct? |
Calling the protected void inject() {
if (!injected) {
injected = true;
// ... injection happens here
}
} |
@bcorso good to know! Thanks for the insight! Is there any plan to support generic types in |
I initially concluded that this wasn't possible (#2042 (comment)) since we couldn't implement the In particular, the generated I think this should be a pretty easy thing for us to fix. |
+1. That would be super helpful! To add |
Please, it's seems solution is hard to implement. So, why don't you build a
small project on how to go about your workaround?
…On Fri, May 13, 2022, 7:15 PM Brad Corso ***@***.***> wrote:
I initially concluded that this wasn't possible (#2042 (comment)
<#2042 (comment)>)
since we couldn't implement the inject() method. However, thinking about
it more we can probably support it similar to the workaround I suggested
above as long as the generic base class is abstract.
In particular, the generated Hilt_MiddleView class wouldn't actually
implement inject(), it would just add the abstract inject() method and
the constructor call for you, just like you're currently doing manually.
I think this should be a pretty easy thing for us to fix.
—
Reply to this email directly, view it on GitHub
<#3370 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AW5JCVYOEOAMSJIU32NQ5RDVJ2S63ANCNFSM5UOO672Q>
.
You are receiving this because you authored the thread.Message ID:
***@***.***>
|
@AndroidEntryPoint abstract class BaseFragment<VM : ViewModel, viewBinding : ViewDataBinding, repository : BaseRepository> : Fragment() { protected lateinit var binding: viewBinding protected lateinit var viewModel: VM var remoteDataSource = RemoteDataSource() ..................................... }
the error code
The text was updated successfully, but these errors were encountered: