Conductor: [QUESTION] Best practices for MVP with plain Conductor

Created on 14 Nov 2016  路  15Comments  路  Source: bluelinelabs/Conductor

On your homepage you say: _"We here at BlueLine Labs tend to use either MVP or MVVM"_.

I want to use MVP with conductor but without mosby and I'm aware of the following stuff:

As I'm pretty new to Android development and completely new to conductor, I still have open questions and I would like to hear how you at BlueLine Labs use MVP with conductor.

Questions:

  • When do you create the presenter in the controller?

    • onAttach() / onDetach()



      • Does not make sense to me as the lifecycle is probably too short then



    • postCreateView() / preDestroyView() --> like mosby-conductor



      • Controllers with RETAIN_RELEASE would then create various presenter instances, right?


      • I'm not sure about this. I guess there is a reason why some controllers retain their view. Wouldn't it then be usefull to retain the presenter instance as well?



    • Constructor(s) / onDestroy()



      • I've never seen this but probably it would have done it like that.


      • What are the downsides I don't see?



  • How do you create the presenter in the controller?

    • by calling its constructor

    • by a presenter factory

    • by injection via e.g. dagger 2

  • How do you deal with state in the presenter?

    • Views can have state (onSaveViewState()/onRestoreViewState())

    • Controllers can have state (onSaveInstanceState()/onRestoreInstanceState())

    • Presenters most probably will have their independent state as well, right?

    • How and when should the presenter's state be saved/restored?



      • never: e.g. because this is done in the controller which calls the presenter's constructor with all parameters necessary to restore the presenter's "state" (not sure if this would be feasible)


      • calling appropriate presenter methods in onSaveViewState()/onRestoreViewState()





        • should the presenter save it's state in the same bundle?





      • calling appropriate presenter methods in onSaveInstanceState()/onRestoreInstanceState()





        • should the presenter save it's state in the same bundle?






  • Would it be possible to see the interfaces and base classes you use at BlueLine Labs for MVP?

    • Maybe just a stripped down version to get the idea.

Thank you in advance.

Most helpful comment

@nomisRev

I have an examples with dagger/mvp on my github. I made it for a talk, but if you have some knowledge about dagger and mvp and how you normally do it. I guess that will be plenty to figure it out.

I'm back at this topic and had a look at your MVP samples. They look very clean and concise. Is there any chance that you extend them with a "mvp-conductor-dagger" variant? I'm sure this would be interesting not only for me.

Cheers.

All 15 comments

When do you create the presenter in the controller?

I have presenters injected by Dagger, which happens in onCreateView. I keep track of whether the controller is already injected, and don't re-inject after config changes (device rotations, ...), this way my presenters survive. I haven't used Mosby, but I remember its main selling point was presenters that survive config changes, so I'm pretty sure it works in a similar way.

How do you create the presenter in the controller?

See above, but using a factory or just constructing it is fine if you haven't used Dagger yet.

How do you deal with state in the presenter?

Views save their own state, most of that happens automatically if you assign them IDs.

I tend to keep my app state (the "data" or "model") separate from the view layer. My presenters survive config changes, but in the rare case the presenter needs to persist state across process deaths, I hand it to the controller, which persists it along with its own state.

but in the rare case the presenter needs to persist state across process deaths, I hand it to the controller, which persists it along with its own state.

How do you do that?

I know that MAY be out of scope, but perhaps using something like mosby might really help you !

@PaulWoitaschek not elegant, but dead simple. Just add a setter to your view interface, keep a field in the controller and add it to/retrieve it from the bundle in onSaveInstanceState/onRestoreInstanceState. You could also ping the presenter in onSaveInstanceState to make it save in the right moment.

As I said, I need to do this very infrequently, so I let myself get away with it.

Thank you for your ansers so far. I would be really happy if some of you could elaborate on the specific bullet points that I've listed above: e.g. why not creating the presenter in the controller's constructor, or HOW should the presenter's state (if any???) be saved/restored, ...

@hannesstruss: Would it be possible to share some code with us? Personally I'd be especially interested in the dagger presenter injection stuff.

@stephanschuster it looks similar to this: https://gist.github.com/hannesstruss/cef55e6d4dd0153e27f72a19a9588f8b

why not creating the presenter in the controller's constructor

In many cases creating presenters depends on a Context being available (e.g. for obtaining the Dagger component), and there is no Context available before the controller is added to an activity.

@stephanschuster I have an examples with dagger/mvp on my github. I made it for a talk, but if you have some knowledge about dagger and mvp and how you normally do it. I guess that will be plenty to figure it out.

In many cases creating presenters depends on a Context being available (e.g. for obtaining the Dagger component), and there is no Context available before the controller is added to an activity.

@hannesstruss hum.. but since the whole purpose of this project is to go with a SingleActivity architecture, what's the point of using the MainActivity Context if you can have the Application's one ?

@theGlenn controllers need to have either an empty constructor or be initializable from a Bundle. Apart from the callbacks that are called with a context, the only other way to obtain an application context from a controller would be a static reference, which should be avoided.

@hannesstruss I usually don't pass a Context to inner parts of Dagger graphs, but the Component itself.
So, if you need to have the Context from inner parts of the graph, simply expose your Context in your Component interface !

@leonardo2204 how do you pass the component into the controller though? Like fragments, controllers are recreated via Bundles e.g. after process deaths. The only way to retrieve a component in the first place is via a context.

@hannesstruss Or you init your component once from your application subclass and access it through a static method. That's what I do so I don't have to create new components for stuff that just requires the application context and not a themed one.

Another small MVP library - https://github.com/bangarharshit/ConductorMVP. You are encouraged to read the code (it is just 2 class).

Treat controller as the presenter since it survives rotation and has a lifecycle where you can unsubscribe to observables and separate the view into a new class

@bangarharshit Makes sense. Since a controller can survive configuration changes, treat it like a presenter is the easiest way to incorporate MVP into Conductor.

@nomisRev

I have an examples with dagger/mvp on my github. I made it for a talk, but if you have some knowledge about dagger and mvp and how you normally do it. I guess that will be plenty to figure it out.

I'm back at this topic and had a look at your MVP samples. They look very clean and concise. Is there any chance that you extend them with a "mvp-conductor-dagger" variant? I'm sure this would be interesting not only for me.

Cheers.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

mradzinski picture mradzinski  路  5Comments

lenguyenthanh picture lenguyenthanh  路  5Comments

EricKuck picture EricKuck  路  5Comments

adipascu picture adipascu  路  6Comments

lenguyenthanh picture lenguyenthanh  路  7Comments