This repository has been archived by the owner on Mar 16, 2021. It is now read-only.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Google announced the architecture components with falls into the same category as
Ti
. It has some feature where ThirtyInch lacks behind: Composition and multiple shared ViewModels per Activity/Fragment. But we can change that.This is the first draft showing a proof of concept. Names and API are very likely to be changed.
ThirtyInch vs Architecture Components ViewModels
I don't want to write a big comparison, here's just a small summary:
Both libs allow devs to move code out of Activities and Fragments to a place where you can execute code when the Activity changes configuration. Architecture Components ViewModels is very Googlely, meaning they are using retained fragments and the nonConfigurationInstance to retain state. ThirtyInch on the other hand moved way from those APIs, putting everything in a Singleton and cleanup when we get the correct callbacks from the system. This allows ThirtyInch to overcome the "Don't keep Activities" case, where the Activity will be destroyed but our Presenters survive because we know the Activity will come back.
Another major difference is that AC ViewModels provide data and can provide state, but only when the view asks for it. Without registering for events a Activity never receives events. This is completely different from a passive View which is often used in MVP. It makes testing hard because you can only test if single methods of the ViewModel behave correctly. You can't test if the view shows all relevant data or sends correct events.
For testability MVP (and therefore ThirtyInch) wins but requires some boilerplate code and learning to get started. AC ViewModels are easier to use but don't move a lot of logic out of Activities.
What the AC ViewModels do very well is composition. One doesn't have to extend a
ViewModelActivity
. EveryAppCompatActivity
can have multiple ViewModels. The same ViewModel instance can also be shared between Fragments and the hosting Activity.Composition in ThirtyInch
ThirtyInch already allows composition using CompositeAndroid. Because of that we already have extracted all logic out of the Framework Activity and Fragment classes into our delegates.
With the latest additions in the support library (FragmentLifecycleCallbacks) and tons of bugfixes thanks to the Architecture Components project (included in 26.0.0+) we are now able to control the delegates only using callbacks from the support library. This allows us to bind Presenters to Activities and Fragments without extending
TiActivity
or using CompositeAndroid.Once this PR is merged we can remove the
plugin
subproject. It's not required anymore. Users using ThirtyInch with CompositeAndroid can then add Presenters to their Activities with an equally simple API.What's open
Shared Presenters
I really like the idea of a shared state (aka ViewModel) between Fragments and it's host Activity. But it doesn't really fit in the MVP approach. Right now we have a 1:1 relationship between Presenter und View. I'm not sure if we can and should solve this.
Current implementation limitations
Right now we have to initialise a
PresenterBinder
in onCreate and pass in thesavedInstanceState
. But I'm sure we could work around this limitation like ViewModels did.What can't be changed it that
PresenterBinder
cannot be initialised as a member variable:Fragment#onAttach
was called.super.onCreate
like Fragments do (onFragmentPreCreated
) where we can get thesavedInstanceState
.The
savedInstanceState
contains aid
of the Activity to detect "same" ones after a configuration change.