How to handle onNewIntent()
Closed this issue · 11 comments
I got a null view in onWakeUp(), if so, where can I yes be assured to have a view ready, isn't that the whole concept of having onWakeUp()?
My fault, I accidently called the presenter to update what it's showing in onCreate, since I need to pass it the current object that needs to be displayed from the intent the activity received. Is there any good way to do this? there is nothing in the presenter code that receives intent from onCreate and from onNewIntent, but this is certainly needed to be dealt with by the presenter. I am using RxJava, should I use a BehaviourSubject?
Thanks.
Not exactly had this problem with onNewIntent()
but with onActivityResult
. The onActivityResult
case is not really solved as of now. The problem is that onActivityResult
is called before onCreate
. Saving the result in a variable and request it from the view in onWakeUp()
is the current "solution".
The onNewIntent()
case can be solved with the same "solution". A easy and predefined way to work with such events should be part of a future release.
I think I didn't explain myself enough. I am implementing a BrowserActivity with the android WebView. In onCreate I receive an url from intent.getData() and I need to pass it to the SitePresenter to instruct the view to display the site (if allowed by business logic). If a new intent is sent while the activity is open, it should update the current site being displayed by calling onSiteLoadRequest() in the presenter. So, who is responsible in saving the state in onSaveInstanceState and restoring it in onCreate?
Also, I want the WebView to restore itself to the current page when the screen orientation changes, but when I save it's state in onSaveInstanceState and load it in onCreate, my onWakeUp gets called and loads the home page of that site after the web view restores it's own state.
I'm a bit confused what to do in such a situation?
ok, simple. Don't use onSaveInstanceState, save the state in the presenter. when you receive a new intent pass it immediately to the presenter (I hope this happens after Activity#onCreate
), maintain the state there and when the view attaches update it accordingly
My problem is that the WebView gives a bundle of its current state, and restores from that bundle. Should I be saving the bundle in the presenter in onDetachView and restoring it at onAttachView, or is this making the presenter too attached to Android api and complicates testing.
Oh, interesting. Hmm...
You cannot use Bundle
in your tests, therefore it's too close to the Android SDK. Sadly I don't have a good solution for you here. WebView Activities often are very simple and don't have business logic. Is MVP here really helpful?
A WebView is so close to the Android SDK, I don't think a MVP abstraction is very useful here.
There's plenty of logic, since this WebView needs to be filtered. Certain links are permitted to go to while others not.
Maybe something along the idea of Icepick would solve this problem, but it would add an additional layer of transformation between the view and the presenter... But the idea would be that the Presenter base class would handle all the View restoration bundles behind the scenes, gaining the presenter's lifecycle instead of the view lifecycle and restoration by parcelers.
When needed, the activity could pass view's bundles (like the webview's) to the presenter in the activity code, not in the presenter's implementation (or possibly, the saveInstance and onCreate could automatically assign them to the Presenter in TiActivity code...). What do you think?
I thought about this a lot. I came to the conclusion that saving the state should be done in the view (Activity
) in onSaveInstance state. It's so tied to the Activity lifecycle and shouldn't be moved to the presenter. The presenter is still able to provide data (such as URIs) and filter them but you should not put any parcelable to the presenter.
See it from this side: Clean MVP would send a link to the webview whenever it get's attached. The webview always loads the given page. This can be very fast especially for local HTML files.
But you don't want to reload the page every time because it's slow. So you cache data in the view layer (Bundle).
Another thing: The WebView
stores a lot of state in the View layer such as the previous page stack, images, websites,... everything a browser knows. This is problematic when you try to save the state in the presenter. The WebView simply doesn't work that way.
What about having a isRestoredFromSavedState() in the Presenter<> class (just like there is isViewAttached()..), since certain presenter logic depends on this... Is this good practice? If so, could this possibly come out in the next version? Thanks!
The presenter lifecycle will not change in the near future. 4 call backs, create/destroy, view attached/detached that's it. When something requires Activity lifecycle methods it should life in the view.
WebView and MVP doen't work together very well, at least not when the presenter is retaining.