CurrentActivityProvider.kt
TLDR
This file provides a CurrentActivityProvider
class that allows retrieving the current activity in an application. It also includes an ActivityProviderCallbacks
class that implements the ActivityLifecycleCallbacks
interface.
Classes
CurrentActivityProvider
The CurrentActivityProvider
class is responsible for providing access to the current activity in the application. It is annotated with @ActivityRetainedScoped
and uses the @EntryPoint
annotation to provide an entry point for the activity component. It contains the following methods:
-
withActivity(block: Activity.() -> T): T
: This method takes a block of code and executes it with the current activity as the receiver. It ensures that the block is executed on the main thread and throws an exception if called after the activity is finished. -
companion object
: This companion object contains two methods:-
onActivityCreated(activity: Activity)
: Sets the current activity to the given activity. -
onActivityDestroyed(activity: Activity)
: Resets the current activity if it matches the given activity.
-
ActivityProviderCallbacks
The ActivityProviderCallbacks
class implements the ActivityLifecycleCallbacks
interface. It is used to intercept and handle activity lifecycle events. It includes empty implementations for all lifecycle methods except for onActivityCreated
and onActivityDestroyed
, which call the corresponding methods in CurrentActivityProvider
to update the current activity.
package org.leakcanary.util
import android.app.Activity
import android.app.Application.ActivityLifecycleCallbacks
import android.os.Bundle
import dagger.hilt.EntryPoint
import dagger.hilt.InstallIn
import dagger.hilt.android.EntryPointAccessors
import dagger.hilt.android.components.ActivityComponent
import dagger.hilt.android.scopes.ActivityRetainedScoped
import dagger.hilt.internal.GeneratedComponentManagerHolder
import javax.inject.Inject
@EntryPoint
@InstallIn(ActivityComponent::class)
interface ActivityProviderEntryPoint {
val activityProvider: CurrentActivityProvider
}
@ActivityRetainedScoped
class CurrentActivityProvider @Inject constructor() {
private var currentActivity: Activity? = null
fun <T> withActivity(block: Activity.() -> T): T {
checkMainThread()
val activity = currentActivity
check(activity != null) {
"Don't call this after the activity is finished!"
}
return activity.block()
}
companion object {
private fun Activity.withProvider(
block: CurrentActivityProvider.() -> Unit
) {
if (this is GeneratedComponentManagerHolder) {
val entryPoint: ActivityProviderEntryPoint =
EntryPointAccessors.fromActivity(this)
val provider = entryPoint.activityProvider
provider.block()
}
}
fun onActivityCreated(activity: Activity) {
activity.withProvider {
currentActivity = activity
}
}
fun onActivityDestroyed(activity: Activity) {
activity.withProvider {
if (currentActivity === activity) {
currentActivity = null
}
}
}
}
}
class ActivityProviderCallbacks : ActivityLifecycleCallbacks {
override fun onActivityCreated(
activity: Activity,
savedInstanceState: Bundle?
) {
CurrentActivityProvider.onActivityCreated(activity)
}
override fun onActivityDestroyed(activity: Activity) {
CurrentActivityProvider.onActivityDestroyed(activity)
}
override fun onActivityStarted(activity: Activity) = Unit
override fun onActivityResumed(activity: Activity) = Unit
override fun onActivityPaused(activity: Activity) = Unit
override fun onActivityStopped(activity: Activity) = Unit
override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) = Unit
}