Protected method not accessible from subclass - android

I know this has been asked before but my problem is strange and I couldn't find an answer.
I have a parent class where a member is declared protected
class BaseContoller<G: BaseContract.BasePresenter, F: BaseModel> {
protected var presenter: G? = null
// ...
}
In each of BaseController's descendants, I refer to presenter with no problem as it is accessible in the same package and subclasses.
One BaseController's descendant has to be extended by other classes too but I have to do one check before of performing certain actions in where presenter is referenced again
class BackupPrinterController<G: BackupPrinterContract.Presenter, F: BaseModel>: BackupController<G, F>
private fun startScan() {
if(this is PrinterAssociationController) {
PrinterConnection.onConnection = { presenter?.onDeviceConnected(it) }
// ...
}
}
}
The strange behaviour comes here, presenter is perfectly accessible only without the filter if(this is PrinterAssociationController), with that if statement, when the onConnection callback is invoked, an IllegalAccessError exception is thrown by presenter
Here is the declaration of PrinterAssociationController
class PrinterAssociationController: BackupPrinterController<PrinterAssociationContract.Presenter, PrinterAssociationModel>(),
PrinterAssociationContract.View
and here is the exception
java.lang.IllegalAccessError: Method 'package.common.base.BaseContract$BasePresenter package.common.base.BaseController.getPresenter()' is inaccessible to class 'package.project.features.shared.controllers.BackupPrinterController$startScan$1' (declaration of 'package.project.features.shared.controllers.BackupPrinterController$startScan$1' appears in /data/app/package.project-1/base.apk:classes2.dex)
at package.project.features.shared.controllers.BackupPrinterController$startScan$1.invoke(BackupPrinterController.kt:53)
at package.project.features.shared.controllers.BackupPrinterController$startScan$1.invoke(BackupPrinterController.kt:35)
at package.project.utils.print.PrinterConnection$scan$1$4.accept(PrinterConnection.kt:84)
at package.project.utils.print.PrinterConnection$scan$1$4.accept(PrinterConnection.kt:24)
at io.reactivex.internal.observers.LambdaObserver.onNext(LambdaObserver.java:63)
at io.reactivex.internal.operators.observable.ObservableFilter$FilterObserver.onNext(ObservableFilter.java:52)
at io.reactivex.internal.operators.observable.ObservableDistinct$DistinctObserver.onNext(ObservableDistinct.java:85)
at io.reactivex.internal.operators.mixed.CompletableAndThenObservable$AndThenObservableObserver.onNext(CompletableAndThenObservable.java:65)
at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.tryEmit(ObservableFlatMap.java:265)
at io.reactivex.internal.operators.observable.ObservableFlatMap$InnerObserver.onNext(ObservableFlatMap.java:562)
at io.reactivex.internal.operators.observable.ObservableDoOnEach$DoOnEachObserver.onNext(ObservableDoOnEach.java:101)
at io.reactivex.internal.operators.observable.ObservableMap$MapObserver.onNext(ObservableMap.java:62)
at io.reactivex.internal.operators.observable.ObservableUnsubscribeOn$UnsubscribeObserver.onNext(ObservableUnsubscribeOn.java:60)
at io.reactivex.internal.operators.observable.ObservableCreate$CreateEmitter.onNext(ObservableCreate.java:66)
at com.polidea.rxandroidble2.internal.serialization.FIFORunnableEntry$1.onNext(FIFORunnableEntry.java:66)
at io.reactivex.internal.operators.observable.ObservableUnsubscribeOn$UnsubscribeObserver.onNext(ObservableUnsubscribeOn.java:60)
at io.reactivex.internal.operators.observable.ObservableSubscribeOn$SubscribeOnObserver.onNext(ObservableSubscribeOn.java:58)
at io.reactivex.internal.operators.observable.ObservableCreate$CreateEmitter.onNext(ObservableCreate.java:66)
at com.polidea.rxandroidble2.internal.operations.ScanOperationApi21$1.onScanResult(ScanOperationApi21.java:77)
at android.bluetooth.le.BluetoothLeScanner$BleScanCallbackWrapper$1.run(BluetoothLeScanner.java:471)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at com.osama.firecrasher.FireLooper.run(FireLooper.kt:39)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6780)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1500)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1390)
I don't understand why this is happening when I put that if statement

Related

Dynamic Feature Crashing Resource not found on Application Relaunch

My app works fine after downloading Dynamic Feature onDemand Module but as soon as I restart my app the app crashes with Exception.
Heres the code that I copied from google dynamic features [sample repo][1]
private fun onSuccessfulLoad(moduleName: String, launch: Boolean) {
if (launch) {
when (moduleName) {
pagesfeatures -> launchActivity(mainActivity)
}
}
}
I have already overridden the code in BaseActivity and App class
open class BaseActivity: AppCompatActivity() {
override fun attachBaseContext(newBase: Context?) {
super.attachBaseContext(newBase)
SplitCompat.install(this)
}
}
public class App extends Application {
#Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
SplitCompat.install(base);
}
}
But its crashing when I revisit the application
The Exception thats occurring in my logs Crashlytics
Fatal Exception: java.lang.RuntimeException: Unable to start activity ComponentInfo{com.qp.readquranoffline.holybookreading/com.mycode.pagesfeature.activities.MainActivity}: android.content.res.Resources$NotFoundException: Resource ID #0x7e010000
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3621)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3866)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2190)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:268)
at android.app.ActivityThread.main(ActivityThread.java:8004)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:627)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:997)
Caused by android.content.res.Resources$NotFoundException: Resource ID #0x7e010000
at android.content.res.ResourcesImpl.getValue(ResourcesImpl.java:248)
at android.content.res.Resources.loadXmlResourceParser(Resources.java:2400)
at android.content.res.Resources.getAnimation(Resources.java:1277)
at android.view.animation.AnimationUtils.loadAnimation(AnimationUtils.java:138)
at com.mycode.quranpagesfeature.activities.MainActivity.onCreate(MainActivity.kt:158)
at android.app.Activity.performCreate(Activity.java:8058)
at android.app.Activity.performCreate(Activity.java:8042)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1315)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3594)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3866)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2190)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:268)
at android.app.ActivityThread.main(ActivityThread.java:8004)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:627)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:997)
[1]: https://github.com/googlearchive/android-dynamic-features
In my case, when there’s a configuration change it also regenerates the Context in my Activity, and loses the resources that have been injected by SplitCompat. I fix it by loading the resources using ContextCompat.
ContextCompat.getDrawable(context, drawable)
And reinject resource when there`s configuration changes using this in activity
override fun onConfigurationChanged(newConfig: Configuration) {
SplitCompat.installActivity( baseContext ?: this)
super.onConfigurationChanged(newConfig)
}

CoroutineExceptionHandler doesn't work with ViewModelScope and Koin

I have a method to fetch devices using coroutines and use viewModelScope.launch to run coroutines. I want to catch errors using CoroutineExceptionHandler, but I get the error:
E/[Koin]: Instance creation error : could not create instance for [Factory:'com.test.presentation.viewModel.ActivateDeviceViewModel']: java.lang.NullPointerException: Parameter specified as non-null is null: method kotlin.jvm.internal.Intrinsics.checkNotNullParameter, parameter context
kotlin.coroutines.CombinedContext.plus(Unknown Source:2)
kotlinx.coroutines.CoroutineContextKt.newCoroutineContext(CoroutineContext.kt:33)
kotlinx.coroutines.BuildersKt__Builders_commonKt.launch(Builders.common.kt:52)
kotlinx.coroutines.BuildersKt.launch(Unknown Source:1)
kotlinx.coroutines.BuildersKt__Builders_commonKt.launch$default(Builders.common.kt:47)
kotlinx.coroutines.BuildersKt.launch$default(Unknown Source:1)
com.test.presentation.viewModel.ActivateDeviceViewModel.fetchDevices(ActivateDeviceViewModel.kt:42)
com.test.presentation.viewModel.ActivateDeviceViewModel.<init>(ActivateDeviceViewModel.kt:29)
com.test.di.ModulesKt$viewModelModule$1$2.invoke(Modules.kt:63)
com.test.di.ModulesKt$viewModelModule$1$2.invoke(Modules.kt:63)
org.koin.core.instance.InstanceFactory.create(InstanceFactory.kt:51)
org.koin.core.instance.FactoryInstanceFactory.get(FactoryInstanceFactory.kt:36)
org.koin.core.registry.InstanceRegistry.resolveInstance$koin_core(InstanceRegistry.kt:103)
org.koin.core.scope.Scope.resolveInstance(Scope.kt:236)
org.koin.core.scope.Scope.access$resolveInstance(Scope.kt:34)
org.koin.core.scope.Scope$get$1.invoke(Scope.kt:199)
org.koin.core.time.MeasureKt.measureDurationForResult(Measure.kt:75)
org.koin.core.scope.Scope.get(Scope.kt:198)
com.test.presentation.fragment.ActivateDeviceFragment$special$$inlined$inject$default$1.invoke(ComponentCallbackExt.kt:69)
kotlin.SynchronizedLazyImpl.getValue(LazyJVM.kt:74)
com.test.presentation.fragment.ActivateDeviceFragment.getViewModel(ActivateDeviceFragment.kt:39)
com.test.presentation.fragment.ActivateDeviceFragment.access$getViewModel(ActivateDeviceFragment.kt:37)
com.test.presentation.fragment.ActivateDeviceFragment$handleActivateDeviceResult$1$1.invokeSuspend(ActivateDeviceFragment.kt:51)
kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
androidx.lifecycle.DispatchQueue.drainQueue(DispatchQueue.kt:75)
androidx.lifecycle.DispatchQueue.resume(DispatchQueue.kt:54)
androidx.lifecycle.LifecycleController$observer$1.onStateChanged(LifecycleController.kt:40)
androidx.lifecycle.LifecycleRegistry$ObserverWithState.dispatchEvent(LifecycleRegistry.java:354)
androidx.lifecycle.LifecycleRegistry.forwardPass(LifecycleRegistry.java:265)
androidx.lifecycle.LifecycleRegistry.sync(LifecycleRegistry.java:307)
androidx.lifecycle.LifecycleRegistry.moveToState(LifecycleRegistry.java:148)
androidx.lifecycle.LifecycleRegistry.handleLifecycleEvent(LifecycleRegistry.java:134)
androidx.fragment.app.Fragment.performStart(Fragment.java:3024)
androidx.fragment.app.FragmentStateManager.start(FragmentStateManager.java:568)
androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:277)
androidx.fragment.app.FragmentStore.moveToExpectedState(FragmentStore.java:113)
androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1327)
androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:2757)
androidx.fragment.app.FragmentManager.dispatchStart(FragmentManager.java:2707)
androidx.fragment.app.Fragment.performStart(Fragment.java:3028)
androidx.fragment.app.FragmentStateManager.start(FragmentStateManager.java:568)
androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:277)
androidx.fragment.app.FragmentStore.moveToExpectedState(FragmentStore.java:113)
androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1327)
androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:2757)
androidx.fragm.
Please tell me what am I doing wrong and how to fix it? Thanks
fragment
class ActivateDeviceFragment : Fragment(R.layout.fragment_activate_device) {
private val viewModel: ActivateDeviceViewModel by inject()
// ....
}
view model
class ActivateDeviceViewModel constructor(
private val activateDeviceUseCase: ActivateDeviceUseCase,
) : ViewModel() {
init {
fetchDevices()
}
private val exceptionHandler = CoroutineExceptionHandler { coroutineContext, throwable ->
Timber.tag("test").d(throwable)
}
private fun fetchDevices() {
viewModelScope.launch(exceptionHandler) {
}
}
}
koin modules
val useCaseModule = module {
single { ActivateDeviceUseCase() }
}
val viewModelModule = module {
viewModel { ActivateDeviceViewModel(get() }
}
It is not related to Koin.
The log shows that the exceptionHandler in viewModelScope.launch(exceptionHandler) is actually null, and which throws NullPointerException.
It is because you trigger the fetchDevices() inside init{}, in which the instantiation of exceptionHandler is not ready (means it is null).
Therefore, you should not call fetchDevices() inside init{}. For example, you could call this in your Fragment onViewCreated(){ viewModel.fetchDevices } instead. It will be fine.

Inlining codes with coroutines to inside of button.setOnClickListener makes app crash

This is the summary of some codes which I am trying to implement.
button.setOnClickListener {
showSomeAnimation()
CoroutineScope(Dispatchers.IO).launch { // this line is UserActivity.kt:138
someNetworkTasks()
withContext(Dispatchers.Main) {
updateUI()
}
}
}
However, once I press the button, java.lang.VerifyError occurs:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.diy.drift, PID: 25461
java.lang.VerifyError: Verifier rejected class com.diy.drift.UserActivity$onCreate$$inlined$forEachIndexed$lambda$1$1: java.lang.Object com.diy.drift.UserActivity$onCreate$$inlined$forEachIndexed$lambda$1$1.invokeSuspend(java.lang.Object) failed to verify: java.lang.Object com.diy.drift.UserActivity$onCreate$$inlined$forEachIndexed$lambda$1$1.invokeSuspend(java.lang.Object): [0xDB] 'this' argument 'Uninitialized Reference: com.diy.drift.UserActivity$onCreate$$inlined$forEachIndexed$lambda$1$1$4 Allocation PC: 217' not instance of 'Precise Reference: com.diy.drift.UserActivity$onCreate$$inlined$forEachIndexed$lambda$1$1$3' (declaration of 'com.diy.drift.UserActivity$onCreate$$inlined$forEachIndexed$lambda$1$1' appears in /data/app/com.diy.drift-fU12pqcCpebCBPw2Tcgk-w==/base.apk!classes2.dex)
at com.diy.drift.UserActivity$onCreate$$inlined$forEachIndexed$lambda$1.onClick(UserActivity.kt:138)
at android.view.View.performClick(View.java:6612)
at android.view.View.performClickInternal(View.java:6581)
at android.view.View.access$3100(View.java:785)
at android.view.View$PerformClick.run(View.java:25904)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:280)
at android.app.ActivityThread.main(ActivityThread.java:6706)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
I thought that there can be some errors on my code and exception weren't printed definitely because the code is inside of lambda. So I extracted all of codes which are in button.setOnClickListener to a function to see what is the problem of my code like this:
fun foo() {
showSomeAnimation()
CoroutineScope(Dispatchers.IO).launch {
someNetworkTasks()
withContext(Dispatchers.Main) {
updateUI()
}
}
}
button.setOnClickListener {
foo()
}
But it worked really well without any exception. Why did this strange thing happen to me?
Try using
GlobalScope.launch {
someNetworkTasks()
}
updateUI()
Hope this helps

How to put logic with eventbus in presenter for Kotlin

Please if you want to devote question write reason to improve.
The problem is I dont know how to implement the eventbus in presenter with Kotlin. It works fine if I implement and subscribe in activity class but when I am trying the same code in the presenter I got an exception. Might be something in Kotlin way of implementation. There must be nothing wrong with eventbus setting up because implementation in view works fine
My activity => constructor of presenter
private val mMainPresenter = MainPresenter(this, MainInteractor(), this)
My presenter
class MainPresenter(var mMainView: MainInterface?, val mMainInteractor: MainInteractor, val mContext : Context){
/**
* Checking if user have language otherwise show list of games
*/
fun checkingLanguage() {
if(mMainInteractor.getUserLanguage() == "") mMainView?.callLanguageDialog()
else EventBus.getDefault().post(LanguageEvent (mMainInteractor.getUserLanguage()))
}
fun registerSubscribers() {
if (!EventBus.getDefault().isRegistered(mContext)) {
EventBus.getDefault().register(mContext)
}
}
#Subscribe
fun inflateGamesList(event: LanguageEvent){
mMainView?.showGamesList(event.language)
} }
Exception code
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.a3802256.zzzz, PID: 13508
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.a3802256.zzzz/com.example.a3802256.zzzz.view.main.MainActivity}: org.greenrobot.eventbus.EventBusException: Subscriber class com.example.a3802256.zzzz.view.main.MainActivity and its super classes have no public methods with the #Subscribe annotation
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2665)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2726)
at android.app.ActivityThread.-wrap12(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1477)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6119)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
Caused by: org.greenrobot.eventbus.EventBusException: Subscriber class com.example.a3802256.zzzz.view.main.MainActivity and its super classes have no public methods with the #Subscribe annotation
at org.greenrobot.eventbus.SubscriberMethodFinder.findSubscriberMethods(SubscriberMethodFinder.java:67)
at org.greenrobot.eventbus.EventBus.register(EventBus.java:140)
at com.example.a3802256.zzzz.view.main.MainPresenter.registerSubscribers(MainPresenter.kt:20)
at com.example.a3802256.zzzz.view.main.MainActivity.onCreate(MainActivity.kt:32)
at android.app.Activity.performCreate(Activity.java:6679)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2618)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2726) 
at android.app.ActivityThread.-wrap12(ActivityThread.java) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1477) 
at android.os.Handler.dispatchMessage(Handler.java:102) 
at android.os.Looper.loop(Looper.java:154) 
at android.app.ActivityThread.main(ActivityThread.java:6119) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776) 
If you want to listen to events in presenter, you should register presenter, and not activity (context). So,
fun registerSubscribers() {
if (!EventBus.getDefault().isRegistered(this)) {
EventBus.getDefault().register(this)
}
}

App Crash once replace Fragment for scoped ViewModel

Bug
I was found an issue when I try to open fragment and then replace with the same fragment.
In our prod application, it's a popular case.
java.lang.IllegalStateException: Definition without any InstanceContext - [type:Scope,scope:'com.abc.view.fragment.BrowseTaskFragment', primary_type:'com.abc.viewModel.BrowseTaskVM']
at org.koin.core.definition.BeanDefinition.resolveInstance(BeanDefinition.kt:72)
at org.koin.core.scope.Scope.resolveInstance(Scope.kt:141)
at org.koin.core.scope.Scope.get(Scope.kt:131)
at com.abc.view.fragment.BrowseTaskFragment$$special$$inlined$inject$1.invoke(Scope.kt:274)
at kotlin.SynchronizedLazyImpl.getValue(LazyJVM.kt:74)
at com.abc.view.fragment.BrowseTaskFragment.getMViewModel(Unknown Source:25)
at com.abc.view.fragment.BrowseTaskFragment.getMViewModel(BrowseTaskFragment.kt:37)
at com.abc.base.BaseFragment.performViewModelBinding(BaseFragment.kt:55)
at com.abc.base.BaseFragment.onViewCreated(BaseFragment.kt:31)
at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManager.java:1471)
at androidx.fragment.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1784)
at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManager.java:1852)
at androidx.fragment.app.BackStackRecord.executeOps(BackStackRecord.java:802)
at androidx.fragment.app.FragmentManagerImpl.executeOps(FragmentManager.java:2625)
at androidx.fragment.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2411)
at androidx.fragment.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManager.java:2366)
at androidx.fragment.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2273)
at androidx.fragment.app.FragmentManagerImpl$1.run(FragmentManager.java:733)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:201)
at android.app.ActivityThread.main(ActivityThread.java:6810)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:547)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:873)
Steps to reproduce the behavior:
I have BottomNavigationView once I tap on existing fragment which is visible, getting above crash.
Koin version: 2.0.1
Module
val viewModelModule = module {
scope(named<BrowseTaskFragment>()) {
scoped { BrowseTaskVM() }
}
}
Application class
startKoin {
androidContext(this#AbcApplication)
modules(listOf(appModule, stateModule, apiModule, viewModelModule))
}
You can do this by create scope.
First in your module class create scope by named koin method
val viewModelModule = module {
scope(named<BrowseTaskFragment>()) {
scoped { BrowseTaskVM() }
}
}
Second in your fragment
private val viewModelScope = getKoin().getOrCreateScope("Scope1",named<BrowseTaskFragment>())
private val browseTaskVM: BrowseTaskVM= viewModelScope.get()
Last in an onDestoy method close your scope.
override fun onDestroy() {
super.onDestroy()
viewModelScope.close()
}
define in application class like this
startKoin {
androidContext(this#ApplicationContext)
// your modules
modules(listOf(your modules))
}
and pass context in you modules

Categories

Resources