Comments (13)
It should not. I'll check this today.
from nucleus.
More specifically, the issue is caused by PresenterHelper only choosing to destroy a presenter in the case that activity.isFinishing() is true.
The fact that the presenter is not destroyed is actually a potentially desirable behavior, in the instance that I want to keep certain presenters around even when their related views are pushed/popped off of the stack. Right now this is not possible because PresenterHelper always creates a new instance of the presenter due to "requestPresenter(view.getClass(), null);"
I would imagine there are a few ways to solve this. Originally I did it by adding an annotation to the presenter class, and then copying the code from DefaultPresenterManager to a custom version that returned the (leaked) instance when providing a presenter of that type. This seems less than ideal.
The biggest issue I tend to run into is that everything in nucleus is locked away. NucleusLayout has a PresenterHelper, but it's private so I can't replace it with my own subclass.
from nucleus.
Sorry, I can not reproduce your issue. Here is the test:
Probably you have an issue somewhere in another place. Can you provide me an example that reproduces the issue?
from nucleus.
The PresenterHelper creates a new presenter instance only if it has been destroyed. This line: https://github.com/konmik/nucleus/blob/master/nucleus/src/main/java/nucleus/view/PresenterHelper.java#L34
from nucleus.
I don't have an example I can put up at the moment, but I'll try to explain what I think causes it:
- Activity is created
- NucleusLayout view is created, which creates a Presenter and a PresenterHelper
- NucleusLayout is added to Activity with addView()
- NucleusLayout is removed from Activity with removeView()
At this point the NucleusLayout is destroyed, which means that PresenterHelper is also destroyed. However, because the main Activity has not been destroyed, the check on this line:
... is not true, so the Presenter is not destroyed.
from nucleus.
Ok, I see. This behavior is intentional.
There is NucleusLayout.destroyPresenter()
method. https://github.com/konmik/nucleus/blob/master/nucleus/src/main/java/nucleus/view/NucleusLayout.java#L79
It is public
for cases like this. When you're detaching a view that has a lifecycle that is different to Activity, you need to call destroyPresenter() to destroy the presenter. A view does not know will it be attached again or not. So it can not just destroy presenter, and this decision is left to the caller.
I have no idea what is the best solution for this case. In my early releases I had enum OnDetachedAction {NONE, DESTROY_PRESENTER, DESTROY_IF_FINISHING}
inside of NucleusLayout
, but I've never used it.
I think I need to highlight this moment in the introduction article.
Thank you for your contribution. :)
from nucleus.
Argh... just when I made a bug case too...
https://github.com/scriptacus/Nucleus-Leak
So here's the thing, I'd actually like the keep that Presenter around for use the next time that view is created. Ideally I could just retain the PresenterHelper, or subclass it in some way... but right now that's not possible so the presenter just leaks. I can do as you suggested and destroy it, but then I lose the functionality of keeping it around.
from nucleus.
If you use view's save/restore, your presenter should be re-attached to a view that is restored from that bundle/parcelable. A pure miracle. ;)
from nucleus.
Sorry this is turning into an android QA thread.
Is there a way to do that without the PresenterHelper creating a new instance of the Presenter? It seems that addView calls onAttachedToWindow() which calls helper.takeView(), which calls requestPresenter with a null bundle. I can probably override onAttachedToWindow() in my view class, but then I would need to pass some sort of state to the view telling it to wait for an onRestoreInstanceState() instead of calling super.onAttachedToWindow().
from nucleus.
You can call view's restore yourself. Here is an extract from one of my projects:
public Parcelable freeze(View view) {
SparseArray<Parcelable> states = new SparseArray<>();
view.saveHierarchyState(states);
Bundle bundle = new Bundle();
bundle.putSparseParcelableArray(STATE_KEY, states);
return bundle;
}
public View unfreeze(Parcelable parcelable) {
Bundle bundle = (Bundle)parcelable;
View view = inflate(...);
view.restoreHierarchyState(bundle.getSparseParcelableArray(STATE_KEY));
return view;
}
add a view after it has been restored, so the presenter will be reattached/created at the right time.
P.S. I'm happy to provide support - you're helping to make this library better. :)
from nucleus.
The introduction article has been enhanced with "View recycling and view stack" section.
http://konmik.github.io/introduction-to-model-view-presenter-on-android.html
from nucleus.
Can you provide any details on how to implement this sort of save/restore with StackLayout + Nucleus? I've been able to do it by restoring the view state (saved in a hashmap on the activity) in each View's onAttachedToWindow, but that seems a bit hacky.
EDIT: I was able to implement this much more elegantly by subclassing StackLayout's DefaultWrappingInftlator.
from nucleus.
I do it like this:
stackLayout.set().setOnDestroyViewListener(new StackLayout.OnDestroyViewListener() {
@Override
public void onExitView(View view) {
if (view instanceof NucleusLayout)
((NucleusLayout)view).destroyPresenter();
}
@Override
public void onFreezeView(View view) {
if (view instanceof NucleusLayout)
((NucleusLayout)view).destroyPresenter();
}
}).apply();
It is a reliable but not so flexible way as I'd like to.
from nucleus.
Related Issues (20)
- Best practice for normal case. (get support.) HOT 3
- Wondering about multiple Presenter endpoint calls (Question) HOT 2
- How to get onComplete using restartable methods? HOT 1
- How could i force restartableFirst.onError with mockito? HOT 1
- RxJava latest version not used. HOT 1
- Console error saving file HOT 1
- Activity method called every time HOT 2
- (Question) Don't keep activieties option HOT 1
- Confusion about restartables and the Activity lifecycle HOT 3
- Does Nucleus support native Fragments? HOT 2
- Throwing VerifyError in < API 21 HOT 1
- Question regarding getView() and reference the View in the presenter. HOT 11
- Nucleus with Dagger 2 HOT 3
- NucleusActionBarActivity with support library 26 HOT 13
- Help with injecting Presenter when using AndroidInjector HOT 3
- Calling setPresenter in OnCreate HOT 2
- clear the delivery cache
- Crashes when starting a new activity using kotlin
- upgrade a new version for androidx, please
- getView() deprecated
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from nucleus.