diff --git a/demo/src/main/java/kaufland/com/demo/bean/FooBean.kt b/demo/src/main/java/kaufland/com/demo/bean/FooBean.kt index 4ec21d2..c38d282 100644 --- a/demo/src/main/java/kaufland/com/demo/bean/FooBean.kt +++ b/demo/src/main/java/kaufland/com/demo/bean/FooBean.kt @@ -28,7 +28,7 @@ open class FooBean : FooBeanInterface{ override fun saySomething(): String { vibrator?.vibrate(100) if(!(mContext is Activity)){ - throw RuntimeException("That should not happen in a SingletonBean") + throw RuntimeException("That should not happen in a non SingletonBean which is ui related") } return "${mContext.getString(R.string.title)} ${value.toString()}" diff --git a/kokain-di/src/main/java/com/schwarz/kokain/di/ActivityContextGuard.kt b/kokain-di/src/main/java/com/schwarz/kokain/di/ActivityContextGuard.kt index 30b1ad2..85e5b74 100644 --- a/kokain-di/src/main/java/com/schwarz/kokain/di/ActivityContextGuard.kt +++ b/kokain-di/src/main/java/com/schwarz/kokain/di/ActivityContextGuard.kt @@ -3,10 +3,13 @@ package com.schwarz.kokain.di import android.app.Activity import android.app.Application import android.content.Context +import android.util.Log import android.view.View import androidx.activity.ComponentActivity import androidx.fragment.app.Fragment +import androidx.lifecycle.Lifecycle import androidx.lifecycle.LifecycleObserver +import androidx.lifecycle.OnLifecycleEvent import com.schwarz.kokain.api.EBean import com.schwarz.kokain.di.observer.ActivityRefered import com.schwarz.kokain.di.scope.BeanScope @@ -17,29 +20,57 @@ class ActivityContextGuard(applicationContext: Application) : LifecycleObserver private var appContext = applicationContext - private var currentRef: WeakReference? = null + private var activityRefs: HashMap = HashMap() - operator fun getValue(thisRef: Any?, property: KProperty<*>): Context { - return if (isReferedByActivity(thisRef)) currentRef?.get() ?: appContext else appContext - } + private class ActivityGuard(activity: ComponentActivity, val map: HashMap) : LifecycleObserver { - private fun isReferedByActivity(thisRef: Any?): Boolean { - if (thisRef is BeanScope && thisRef.scope == EBean.Scope.Singleton) { - return false + private val reference = activity.toString() + + private var currentRef: WeakReference = WeakReference(activity) + + init { + if(activity.lifecycle.currentState != Lifecycle.State.DESTROYED){ + activity.lifecycle.addObserver(this) + map[reference] = this + }else{ + currentRef.clear() + } } - if (thisRef is ActivityRefered) { - return thisRef.activityRef?.equals(currentRef?.get()?.toString()) ?: false + + fun isSame(activity: ComponentActivity) : Boolean{ + return currentRef.get() == activity } - if (thisRef is Fragment) { - return thisRef.activity?.equals(currentRef?.get()?.toString()) ?: false + + @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY) + fun onDestroy(){ + currentRef.clear() + map.remove(reference)?.onDestroy() + } + + fun getRef(): Context? { + return currentRef?.get() } - if (thisRef is Activity) { - return thisRef?.equals(currentRef?.get()?.toString()) + + } + + operator fun getValue(thisRef: Any?, property: KProperty<*>): Context { + return findReferredGuard(thisRef)?.getRef() ?: appContext + } + + private fun findReferredGuard(thisRef: Any?): ActivityGuard?{ + if (thisRef is BeanScope && thisRef.scope == EBean.Scope.Singleton) { + return null } - if(thisRef is View){ - return thisRef?.context?.equals(currentRef?.get()?.toString()) ?: false + + val ref : String? = when(thisRef){ + is ActivityRefered -> thisRef.activityRef + is Fragment -> thisRef.activity?.toString() + is Activity -> thisRef?.toString() + is View -> thisRef.context?.toString() + else -> null } - return false + + return activityRefs[ref] } fun updateRefererer(thisRef: Any?, bean: Any?) { @@ -61,9 +92,10 @@ class ActivityContextGuard(applicationContext: Application) : LifecycleObserver } fun onNewContext(activity: ComponentActivity) { - if (currentRef?.get() != activity) { - currentRef?.clear() - currentRef = WeakReference(activity) + + if(activityRefs[activity.toString()]?.isSame(activity) == true){ + return } + ActivityGuard(activity, activityRefs) } }