Giter VIP home page Giter VIP logo

Comments (13)

konmik avatar konmik commented on August 21, 2024

It should not. I'll check this today.

from nucleus.

scriptacus avatar scriptacus commented on August 21, 2024

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.

konmik avatar konmik commented on August 21, 2024

Sorry, I can not reproduce your issue. Here is the test:

https://github.com/konmik/nucleus/blob/master/nucleus/src/androidTest/java/nucleus/view/NucleusLayoutTest.java#L45

Probably you have an issue somewhere in another place. Can you provide me an example that reproduces the issue?

from nucleus.

konmik avatar konmik commented on August 21, 2024

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.

scriptacus avatar scriptacus commented on August 21, 2024

I don't have an example I can put up at the moment, but I'll try to explain what I think causes it:

  1. Activity is created
  2. NucleusLayout view is created, which creates a Presenter and a PresenterHelper
  3. NucleusLayout is added to Activity with addView()
  4. 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:

https://github.com/konmik/nucleus/blob/master/nucleus/src/main/java/nucleus/view/PresenterHelper.java#L56

... is not true, so the Presenter is not destroyed.

from nucleus.

konmik avatar konmik commented on August 21, 2024

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.

scriptacus avatar scriptacus commented on August 21, 2024

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.

konmik avatar konmik commented on August 21, 2024

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.

scriptacus avatar scriptacus commented on August 21, 2024

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.

konmik avatar konmik commented on August 21, 2024

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.

konmik avatar konmik commented on August 21, 2024

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.

scriptacus avatar scriptacus commented on August 21, 2024

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.

konmik avatar konmik commented on August 21, 2024

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)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.