-
Notifications
You must be signed in to change notification settings - Fork 155
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
migrating to Flow, mortar, dagger2 (and Anko) woes... #163
Comments
A) The documentation says that you can create custom mortar scopes but how do you do that ?
I would guess that you have to wrap a context in a custom MortarContext, whose getSystemService() method returns the custom mortarScope instead of the root Mortar Scope. But when/where do you do that with Flow ? In the Flow Dispatcher ? Could we have a flow+mortar+dagger2 sample with a custom MortarScope for some flow screen ? Let's see... This contextFactory is given a new MortarContextFactory() that uses a ScreenScoper that uses dagger1 because of this part :
.withService(ObjectGraphService.SERVICE_NAME, So... I would need to change this part from the dagger1 way to the dagger2 way... Instead of dagger1 subgraph, I guess that we are supposed to use subcomponent (:/ and as I'm a complete begnner with Dagger2, this sounds like a lot of work/boilerplate to me... and I don't know if I'm capable to do that) Also... dagger2 is for dependency injection... I just want to have a path-scoped MortarScope. Mmmh, I compared the code in the mortar sample and in the presenta library code and both use There is a difference in the ScreenScoper and the screenScoper.getScreenScope-) though The one in the mortar sample supports some dagger1 service, and the one in the presenta library builds a child mortar scope that supports 2 services (Dependency injection and presenter, that works through annotated paths) : public MortarScope getScreenScope(Context context, String name, Path path) {
} ...mhhh, so this is how child mortar scope creation looks like.... |
B) I have started investigating how to restore/save states.... Though I have created a mortar scope for my paths, it looks like onSave is never called. I'm using a ViewPresenter with the Singleton annotation.... Apparently, when my MortarActivity fires Which explains why I don't get any onSave call in my presenter... there are no services to save. wow... Mortar takes a parent scope and a context to wrap it in a MortarContextWrapper that is itself wrapped in a TearDownContext (that is also a ContextWrapper) /me's confidence in resolving his problem by himself is slowly dwindling... |
The Exception message in there is wrong : there is no "withScopedService" method, there is an overloaded |
I made a example project with mortar flow dagger2, up to date with latest versions of those libs: https://github.com/lukaspili/Mortar-Flow-Dagger2-demo If you still have any troubles, you should use stackoverflow rather than this issue page. Or use my repo issue page if you have troubles regarding my implementation of mortar/flow/dagger2. |
Thanks for this sample. I'll take a very good look at it. It's nice to have an up to date dagger2 + mortar + flow sample. I'm sorry though, despite your advice, I think I'll keep on posting troubles/findings and workaround here because I think I'm really reporting an important issue of the mortar (+ flow+ dagger) library : It is lacking in documentation (what is in the readme is really minimal,the doc in the code source too sometimes) in a few places and it brings pain to the user of the lib that is left in the dark. For example :
Basically, you have to look at the code source or to figure it out yourself. I have already spent quite a lot of time looking at code source, googling, reading blogs, trying to figure out how things should work and I'm still not done... :/ |
So... In my dictionary app, the user might navigate from screen to screen like this : And to synthetize... -> A presenter that is able to (delegate) handle 2 current views and ignore 0+ obsolete views is needed. -> or maybee, in the App have 2 sets of view :/ and alternate so that animations don't mess with presenters.... like -> a singleton parentPresenter, that injects/delegates differents subPresenters depending on Path.get(context).someVariable -- a bit like the stackoverflow solution |
I still have issues with converting my App to Mortar + Flow + Dagger2. myPresenter.onSave() method is not called because there is no scoped service in the associated BundleService because the activity scope got teared down and another blank activity scope replaced it... O.o I have a hard time figuring out what is happening because there is no debug code for MortarScope, BundleServiceRunner... (but luckily lots of vars in there are public or package private/internal) so I had to write my own debug code like package mortar.bundler import android.content.Context fun Context.debugServices() : String { fun Context.mortarDebug(tag:String, details:Boolean = false) :Unit = if (details) and... package mortar import android.content.Context fun MortarScope.debug() =""" fun MortarScope.fullDebug() :String { fun Context.debug() : String { hint hint : it would be nice to have nice debug/toString methods in the flow/mortar libs |
Also, I have some doubt about the dagger2-sample way of implementing getSystemService in the activity : @OverRide public Object getSystemService(String name) {
} If your activityScope got teared down (like in my case) for an unknown reason, I think that the way the activityScope was created in the dagger1 sample was better, considering that aspect (it will crash the app with the activityScope not being found and a stack trace) |
Now... I don't know if I'll manage to make all of this work and I'm already quite burned out but I really need this to work so let's make some more tries... :/ /me will now look at the suspicious oldPath.destroyNotIn(context, contextFactory) calls that might destroy the bad contexts if I somehow messed the history (right ?)... lots of private vars/methods in there and no debug function :( it's not gonna be fun looking for what's wrong... Also, I'm still not understanding how the @scope anotation work/should be used |
Minor comment: override getSystemService in your Application object, not your Activity. |
Thanks for the advice, I'll try to do that (yet, we still have to add the flowService in the activity, as in the sample). Also, I think that I managed to fix my main issue : -> Using class name for scopeNames is bad in most cases : as soon as you have 2+ screens using the same class (with or without different members), you'll run into bugs and really difficult to find/figure out/fix issues, because the scope name collisions will make some scopes to get unexpectly destroyed and you'll then start to get NPE/weird behavior in unexpected places/at unexpected times It's much better to use copeNames dependant on the instance of the screen. So, in the MortarContextFactory for the mortar-sample, this piece of code is really really evil (took me 1 week to solve this :/). Your sample might work (I didn't try), but noobs like me that will want to build on the sample to integrate flow/mortar/dagger in their apps will get burned bad. Strangely, this snipet is still in the master branch when the following PR should have fixed this already : |
While i know this is outdated, but I put together a sample (a while ago, actually) that has run into similar caveats and therefore makes a comment on them in that regard - which is why my |
Though I worked around the LayoutInflater bug that swaps PathContext with AppCompatActivity by using Anko to instanciate my views with the right context, I still have problems migrating my app to Dagger2, Flow & Mortar :
I know that takeView/dropView might be called out of order and read the recommandations in the source code
I used print statements to figure out what was happening when I set a new View with flow but there is something suscpiscious happening : I get a lot of dropView/takeView (some out of order) and view creations (like a total of 13 of those calls each time I set a view)
I would like to use those, but havent figured out how to have them yet by looking at the doc on those sites :
https://github.com/square/flow (for the flow + path concepts)
https://github.com/square/mortar (there doesn't seem to be a sample for mortar+flow+dagger2, though it looks like there is one with mortar+flow+dagger1, with a ScreenScoper that uses Dagger1 ObjectGraph)
pyricau/dagger2-mortar-flow-experiment#2
#129
https://github.com/techery/presenta
https://github.com/lukaspili/Auto-Mortar
https://github.com/lukaspili/Auto-Dagger2
I was hoping that Flow/Mortar would make things simpler for me but, at this point, this isn't the case.
I'll post my progress here (to get some help/insight...and to help others that might have the same trouble than me)
The text was updated successfully, but these errors were encountered: