aipok
09/16/2020, 12:41 PMoverride val scope: Scope by lazy { koin.createScope(scopeID, getScopeName(), this) }
in my child fragment which extends from ScopeFragment
. For some reason it gives me else condition and exception NoScopeDefFoundException
from onViewCreated
method.
val scopeDefinition = _scopeDefinitions[qualifier.value]
return if (scopeDefinition != null) {
val createdScope: Scope = createScope(scopeId, scopeDefinition, source)
_scopes[scopeId] = createdScope
createdScope
} else {
throw NoScopeDefFoundException("No Scope Definition found for qualifer '${qualifier.value}'")
}
Should I declare each fragment scope in my module before I can use or why I could get this error in 2.2.0-beta-1
version?
Also it seem to call createScope
and fail in onViewCreated
because of this line
koin._logger.debug("Open fragment scope: $scope")
in ScopeFragment
Update: after a bit of tries. If I declare scope for a fragment like this
scope(named<ChildFragment>()) { }
It still not work, but I remember it was mentioned that empty declarations will not be allowed… so it works it I declare something scoped
scope(named<ChildFragment>()) {
scoped { (activity: BaseActivity) -> CustomTabsHelper(activity) }
}
But this is very weird that I have to declare scope before the fragment createScope
. My assumption was that each ScopeFragment
is able to create its own scope and I can use that scope anytime I need it. Since all my fragment as extended from the same BaseFragment or similar. This is very unusable since I can’t extend from ScopeFragment
only on some of them.
From other hand declaring useless scopes in modules for each and every fragment I have this is even more work. Not sure what was the idea behind this change. With lifecycle it was much easier (like is it if you need it or just skip it).
As usual any feedback or discussions are welcome 😄
Koin is the best anyway 🤟sebastien.rouif
09/17/2020, 3:16 PMin my child fragment
do you have nested fragments ?
if you use ScopeFragment
declare a
scope<ChildFragment {
// you needs something here
}
sebastien.rouif
09/17/2020, 3:16 PMfactory { DumyDef() }
sebastien.rouif
09/17/2020, 3:16 PMinternal class DumyDef
aipok
09/17/2020, 5:28 PMscope
for each and every fragment that will subclass my base fragment class.
It looks like I need to avoid using ScopeFragment
for now and just use an Activity and get all the required instances from the parent activity.aipok
10/06/2020, 5:20 AMScopeFragment
but making the scope it creates optional. I’m having lots of component fragments which are using shared VM from ScopeActivity
and I have my activity subclass it. Sometimes those fragments are using their scope for creating their own modules etc, but mostly they are not.
It seems I could not use only ScopeActivity
and I have to use ScopeFragment
as well in order to get scope of the activity correctly.
But right now I have to declare each and every fragment inside module in order to avoid crash during fragment initialization. I posted this before here as well, but not sure if you saw it or not. The information about the crash I mentioned you can find in my post above in this thread.sebastien.rouif
10/06/2020, 10:18 AMaipok
10/06/2020, 10:20 AMrequireScopeActivity
and get shared instance of VM from its scopesebastien.rouif
10/06/2020, 10:26 AMaipok
10/06/2020, 10:44 AMrequireScopeActivity<ProcessActivity>().getViewModel()
arnaud.giuliani
10/06/2020, 10:46 AMrequireActivity()
is not enough then?arnaud.giuliani
10/06/2020, 10:47 AMaipok
10/06/2020, 10:50 AMScopeActivity
and ScopeFragment
meant to be used. And why requireScopeActivity
is needed etc. Current I workaround it with creating my own ScopeFragment
copy by wrapping the log calls with try. Which solves the issue.sebastien.rouif
10/06/2020, 11:23 AMaipok
10/06/2020, 1:45 PMviewModel<SomeVM>()
in activity and call the sharedViewModel
inside my fragments and that worked well, with new version I could not do that anymore, thats why I’m trying to figure out how should I deal now with similar scenarios.arnaud.giuliani
10/06/2020, 2:24 PMwith new version I could not do that anymoreYou don’t have to use ScopeFragment or ScopeActivity if you don’t use scopes at all
arnaud.giuliani
10/06/2020, 2:24 PMaipok
10/06/2020, 2:55 PMgetSharedViewModel
. Just found it now again 😄 .
But have an ability to subclass ScopeFragment
without requirement for creating the scope is still valid. Since if I have the parent fragment for most of my component fragments to reuse core logic. And some of those fragment might need the fragment scope. But since they all have to subclass base fragment, I can’t extend the ScopeFragment
for some of them. Anyway, thanks for your responses and Koin is 🚀arnaud.giuliani
10/06/2020, 3:04 PMarnaud.giuliani
10/06/2020, 3:04 PMaipok
10/06/2020, 3:05 PMabstract class OptionalScopeFragment(
@LayoutRes contentLayoutId: Int = 0
) : Fragment(contentLayoutId), KoinScopeComponent {
override val koin by lazy { getKoin() }
override val scope: Scope by lazy { createScope() }
private var hasScopeDefinition = false
val scopeActivity: ScopeActivity?
get() = activity as? ScopeActivity
inline fun <reified T : ScopeActivity> requireScopeActivity(): T = activity as? T
?: error("can't get ScopeActivity ${T::class}")
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
hasScopeDefinition = try {
koin.logger.debug("Open fragment scope: $scope")
true
} catch (e: NoScopeDefFoundException) {
logw { "koin:: could not open the scope for ${this.javaClass.name}" }
false
}
}
override fun onDestroy() {
super.onDestroy()
if (hasScopeDefinition) {
koin.logger.debug("Close fragment scope: $scope")
scope.close()
}
}
}
Might be ugly but works 😄arnaud.giuliani
10/06/2020, 3:20 PMarnaud.giuliani
10/06/2020, 3:20 PM