You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository was archived by the owner on Feb 26, 2023. It is now read-only.
Repository navigation
This repository was archived by the owner on Feb 26, 2023. It is now read-only.
Always call #onNewIntent(), even without @AfterExtras method(s) #1578
If there is any method with @AfterExtras passing new Intent to activity causes calling onNewIntent(), from there setIntent() and finally injectExtras_() where all new extras are set. And it's great.
On the other hand if there is no any @AfterExtras method generated subclass has no onNewIntent() method, and in result extra is not updated.
This is unfortunate if extra does not cause any instant action, but is used later - for example in my case there is only one extra that is passed by to next activity, without any operations on it. So currently I had to add blank method with @AfterExtras annotation just to make sure that onNewIntent() is generated.
But setIntent() is not called if there is no @AfterExtras method. On the other hand, if there is any, it is called. So depending on having any @AfterExtras methods extras are or are not updated - it's inconsistency for me.
The extras are injected in two places In setIntent() and in onCreate(). So they will be injected even if there is no @AfterExtras method, in onCreate(). If the Activity is not created, just a new intent reaches the Activity, then we only inject the extras if the setIntent() method is called. Which seem to be correct to me, because if that is not called, the new Intent does not really belong to the Activity. The @AfterExtras annotation clearly states the the user wants to work with the injected extras, so we call setIntent() there.
You are saying that you are just using @AfterExtras as dummy now. My question is: which lifecycle method you use to actually work with the newly injected extras?
You are saying that you are just using @AfterExtras as dummy now. My question is: which lifecycle method you use to actually work with the newly injected extras?
In my (very uncommon I think ;-) ) case I'm only passing this particular extra (if exists) to the next Activity, without interacting with it. The case is this Intent comes from notification click and next Activity must be informed, what was in this notification.
Please consider following two example Activities:
@EActivitypublicclassAbcActivityextendsActivity {
@ExtraStringfirstExtra;
@ExtraStringsecondExtra;
@AfterExtrasvoiddoSthWithSecondExtra() {
if (secondExtra != null) {
Log.i("Second extra is: " + secondExtra)
}
}
@Click(R.id.my_button)
voidonMyButtonClick() {
Log.i("First extra is: " + firstExtra)
}
}
@EActivitypublicclassXyzActivityextendsActivity {
@ExtraStringfirstExtra;
@Click(R.id.my_button)
voidonMyButtonClick() {
Log.i("First extra is: " + firstExtra)
}
}
And now passing new Intent with single top flag etc. (so without re-creating the Activity) and then clicking the button will result in different values logged.
I agree this is an uncommon case. In AA, we can always support the most common case, because we have to decide things in compile-time, which makes adding options really hard.
Can you just use the workaround? Or something wrong with that?
Yea, it works with workaround (empty @AfterExtras method). But maybe at least add some info in wiki? I can do this if you want.
And about making decisions at compile-time - from my point of view onNewIntent() should be generated always if there is any @AfterExtras method (as it is currently) OR @Extra field. Looks like adding holder.getOnNewIntent(); into ExtraHandler should do the thing and I can try to do this as well, if you would like me to. But I understand it may be not so easy as it looks like at first glance.
@WonderCsabo i think this makes sense and i see no reason not to support this. i even have a similar case where i use only one of my four extras inside @AfterExtras and the others in either click or EventBus events. here i have the @AfterExtras but that method could become deprecated in near future.
OK, let's override onNewIntent() and call setIntent() always. This is maybe a breaking change, because some people may expect the original Intent with getIntent() if only uses @Extra.
inject in onCreate() and onNewIntent() but not call setIntent(). the user has to override onNewIntent() if he needs the new Intent in getIntent() instead of the original one.
but that might mean a silently breaking change. as one may rely on the setIntent() call when using getIntent() somewhere.
After thinking this trough i came to this conclusion:
We should inject extras as we do currently, meaning in onCreate() and in setIntent(). The injected extras are becoming the state of the Activity. If we would inject extras in onNewIntent(), the state would contain any last Intent extras which may be not interesting to the object at all, and also makes the real last interesting extras inaccessible in the injected fields. Also, the current way stores the same values in the fields as getIntent().getExtras() do, which is consistent.
I think we should not override onNewIntent(), ever, even with @AfterExtras. We could add a flag to @AfterExtras but what happens when there are multiple methods annotated with that, or after extras methods are coming from the super classes? So the user should have the liberty to decide whether an Intent should be set to the Activity or not.
by default never override onNewIntent() to call setIntent()
inject in onCreate() and setIntent()
(maybe) add an option to @AfterExtras to yet again generate a onNewIntent() that calls setIntent()
this sounds ok, but i would not add the option to @AfterExtras but to @EActivity that bypasses the issue of having more than one @AfterExtras and it is imo a better place for an activity wide option. also this allows to have the overriden onNewIntent() even when not using @AfterExtras.
also i think if the user has a case where the parent and the child activity require diffrent behaviour related to setIntent() the user has a bigger problem than we can take care of.
I do not think @EActivity is a good place for this, the purpose of it is different.
If have a different idea: add processing option which decides whether do override onNewIntent() or not. This could be true by default, which is okay for most of the projects.
However this is also not really cool. This is a tough problem, and it seems there is no best-case scenario. :(
I'd prefer the @EActivity over a processing option as this allows to have a per activity setting.
i belive having the option on @EActivity is the best solution. one can configure the behaviour on a per activity base and can have onNewIntent() independently of @AfterExtras and @Extra - this way he could even benefit from it when not using any of the extras related annotations.
I would have injected extras only onCreate and setIntent. If the developer wants, he still can override onNewIntent to call setIntent.
To help him doing so, we could add a new annotation on the Activity class (@SetIntentOnNewIntent) but I don't think it helps a lot.
OK, a decision has been made. So the only action for use is remove the onNewIntent override. @dodgex can you do this as the original author of that code?
Activity
WonderCsabo commentedon Oct 7, 2015
The
@Extras are injected every time whensetIntent()is called. I am not sure we should change that toonNewIntent(). @dodgex @yDelouis ?m-radzikowski commentedon Oct 7, 2015
But
setIntent()is not called if there is no@AfterExtrasmethod. On the other hand, if there is any, it is called. So depending on having any@AfterExtrasmethods extras are or are not updated - it's inconsistency for me.WonderCsabo commentedon Oct 7, 2015
The extras are injected in two places In
setIntent()and inonCreate(). So they will be injected even if there is no@AfterExtrasmethod, inonCreate(). If theActivityis not created, just a new intent reaches theActivity, then we only inject the extras if thesetIntent()method is called. Which seem to be correct to me, because if that is not called, the newIntentdoes not really belong to theActivity. The@AfterExtrasannotation clearly states the the user wants to work with the injected extras, so we callsetIntent()there.You are saying that you are just using
@AfterExtrasas dummy now. My question is: which lifecycle method you use to actually work with the newly injected extras?m-radzikowski commentedon Oct 8, 2015
In my (very uncommon I think ;-) ) case I'm only passing this particular extra (if exists) to the next Activity, without interacting with it. The case is this Intent comes from notification click and next Activity must be informed, what was in this notification.
Please consider following two example Activities:
And now passing new Intent with single top flag etc. (so without re-creating the Activity) and then clicking the button will result in different values logged.
WonderCsabo commentedon Oct 8, 2015
I agree this is an uncommon case. In AA, we can always support the most common case, because we have to decide things in compile-time, which makes adding options really hard.
Can you just use the workaround? Or something wrong with that?
m-radzikowski commentedon Oct 8, 2015
Yea, it works with workaround (empty
@AfterExtrasmethod). But maybe at least add some info in wiki? I can do this if you want.And about making decisions at compile-time - from my point of view
onNewIntent()should be generated always if there is any@AfterExtrasmethod (as it is currently) OR@Extrafield. Looks like addingholder.getOnNewIntent();intoExtraHandlershould do the thing and I can try to do this as well, if you would like me to. But I understand it may be not so easy as it looks like at first glance.dodgex commentedon Oct 8, 2015
@WonderCsabo i think this makes sense and i see no reason not to support this. i even have a similar case where i use only one of my four extras inside
@AfterExtrasand the others in either click or EventBus events. here i have the@AfterExtrasbut that method could become deprecated in near future.WonderCsabo commentedon Oct 8, 2015
OK, let's override
onNewIntent()and callsetIntent()always. This is maybe a breaking change, because some people may expect the originalIntentwithgetIntent()if only uses@Extra.WonderCsabo commentedon Oct 11, 2015
@dodgex should we move extra injecton to
onNewIntent, or always callsetIntent?dodgex commentedon Oct 12, 2015
@WonderCsabo that is a difficult question. is
onNewIntentcalled when the activity is created?i think i would keep it in
setIntent.dodgex commentedon Oct 12, 2015
but the best option would be somehow to allow the developer to decide where it should be injected and if
setIntentshould be called fromonNewIntentthis might be an interesting read
WonderCsabo commentedon Oct 12, 2015
What about setting the extras in both
onNewIntent()andonCreate(). And only callsetIntent()with@AfterExtras(or not call that at all)?dodgex commentedon Oct 12, 2015
i think we should do it that way.
inject in
onCreate()andonNewIntent()but not callsetIntent(). the user has to overrideonNewIntent()if he needs the newIntentingetIntent()instead of the original one.but that might mean a silently breaking change. as one may rely on the
setIntent()call when usinggetIntent()somewhere.WonderCsabo commentedon Oct 12, 2015
Yeah, that would be a breaking change, we will mark it in the release notes. I agree, this is a best solution, and gives the user maximum flexibility.
4 remaining items
m-radzikowski commentedon Oct 20, 2015
But please remember that by default AA calls setIntent() in onNewIntent() right now in most of the cases - if there is any
@Extrafield.WonderCsabo commentedon Oct 20, 2015
That is not true, only if there is a method annotated with
@AfterExtras.m-radzikowski commentedon Oct 20, 2015
Sorry, you are right. But still - sometimes AA calls setIntent(), sometimes it does not.
WonderCsabo commentedon Oct 21, 2015
After thinking this trough i came to this conclusion:
We should inject extras as we do currently, meaning in
onCreate()and insetIntent(). The injected extras are becoming the state of theActivity. If we would inject extras inonNewIntent(), the state would contain any lastIntentextras which may be not interesting to the object at all, and also makes the real last interesting extras inaccessible in the injected fields. Also, the current way stores the same values in the fields asgetIntent().getExtras()do, which is consistent.I think we should not override
onNewIntent(), ever, even with@AfterExtras. We could add a flag to@AfterExtrasbut what happens when there are multiple methods annotated with that, or after extras methods are coming from the super classes? So the user should have the liberty to decide whether anIntentshould be set to theActivityor not.WonderCsabo commentedon Oct 28, 2015
@dodgex @yDelouis what do you think about my last proposal?
dodgex commentedon Oct 28, 2015
to clarify how i understand your proposal:
onNewIntent()to callsetIntent()onCreate()andsetIntent()@AfterExtrasto yet again generate aonNewIntent()that callssetIntent()this sounds ok, but i would not add the option to
@AfterExtrasbut to@EActivitythat bypasses the issue of having more than one@AfterExtrasand it is imo a better place for an activity wide option. also this allows to have the overridenonNewIntent()even when not using@AfterExtras.also i think if the user has a case where the parent and the child activity require diffrent behaviour related to
setIntent()the user has a bigger problem than we can take care of.WonderCsabo commentedon Oct 28, 2015
I do not think
@EActivityis a good place for this, the purpose of it is different.If have a different idea: add processing option which decides whether do override
onNewIntent()or not. This could be true by default, which is okay for most of the projects.However this is also not really cool. This is a tough problem, and it seems there is no best-case scenario. :(
dodgex commentedon Oct 28, 2015
I'd prefer the
@EActivityover a processing option as this allows to have a per activity setting.i belive having the option on
@EActivityis the best solution. one can configure the behaviour on a per activity base and can haveonNewIntent()independently of@AfterExtrasand@Extra- this way he could even benefit from it when not using any of the extras related annotations.WonderCsabo commentedon Oct 28, 2015
I think we should not add more properties to
@EActivity, but we may could introduce a new annotation for this.dodgex commentedon Oct 28, 2015
@OverrideOnNewIntent? :Da new annotation is ok too. at least it should be possible to decide that on a per activity base.
yDelouis commentedon Oct 29, 2015
I would have injected extras only
onCreateandsetIntent. If the developer wants, he still can overrideonNewIntentto callsetIntent.To help him doing so, we could add a new annotation on the
Activityclass (@SetIntentOnNewIntent) but I don't think it helps a lot.WonderCsabo commentedon Oct 29, 2015
OK, a decision has been made. So the only action for use is remove the
onNewIntentoverride. @dodgex can you do this as the original author of that code?dodgex commentedon Oct 29, 2015
I just broke my own app/code with this PR :/ :D
WonderCsabo commentedon Oct 29, 2015
Implemented, thanks for the cooperation everybody.
@m-radzikowski please override
onNewIntent()manually when you need it.