Skip to content

Instantly share code, notes, and snippets.

@Andrew0000
Created May 16, 2023 07:51
Show Gist options
  • Save Andrew0000/22bd4333e200da6f3ad4473bcaba4314 to your computer and use it in GitHub Desktop.
Save Andrew0000/22bd4333e200da6f3ad4473bcaba4314 to your computer and use it in GitHub Desktop.
ActivitiesTracker
import android.annotation.SuppressLint
import android.app.Activity
import android.app.Application
import android.os.Bundle
import timber.log.Timber
import java.lang.ref.WeakReference
class ActivitiesTracker {
private val createdActivities = mutableListOf<WeakReference<Activity>>()
private val startedActivities = mutableListOf<WeakReference<Activity>>()
@SuppressLint("BinaryOperationInTimber")
fun init(app: Application) {
app.registerActivityLifecycleCallbacks(
object : Application.ActivityLifecycleCallbacks {
override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {
createdActivities.addDistinct(activity)
Timber.d("[ActivitiesTracker] created: " +
"${activity}, ${createdActivities.size}")
}
override fun onActivityStarted(activity: Activity) {
startedActivities.addDistinct(activity)
}
override fun onActivityResumed(activity: Activity) {}
override fun onActivityPaused(activity: Activity) {}
override fun onActivityStopped(activity: Activity) {
startedActivities.removeLastActivity(activity)
}
override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {}
override fun onActivityDestroyed(activity: Activity) {
createdActivities.removeLastActivity(activity)
Timber.d("[ActivitiesTracker] destroyed: " +
"${activity}, ${createdActivities.size}")
}
}
)
}
@Suppress("Unused")
fun getCreated(): Activity? = createdActivities.getLastExisting()
@Suppress("Unused")
fun getStarted(): Activity? = startedActivities.getLastExisting()
@Suppress("Unused")
fun allCreated(): List<Activity> =
createdActivities.mapNotNull { it.get() }
@Suppress("Unused")
fun finishAllExcept(except: Activity) {
allCreated().forEach { activity ->
if (activity != except) {
Timber.d("[ActivitiesTracker] finish: $activity")
activity.finishAndRemoveTask()
}
}
}
private fun List<WeakReference<Activity>>.getLastExisting(): Activity? {
if (BuildConfig.DEBUG) {
forEach {
Timber.d("[ActivitiesTracker] getLastExisting list: ${it.get()}")
}
}
asReversed().forEach {
val activity = it.get()
if (activity != null) {
return activity
}
}
return null
}
private fun MutableList<WeakReference<Activity>>.removeLastActivity(activity: Activity) {
val asReversed = asReversed()
asReversed.forEachIndexed { index, weakReference ->
val fromRef = weakReference.get()
if (fromRef === activity) {
asReversed.removeAt(index)
return
}
}
}
private fun MutableList<WeakReference<Activity>>.addDistinct(activity: Activity) {
if (!containsActivity(activity)) {
add(activity.weak())
}
}
private fun List<WeakReference<Activity>>.containsActivity(activity: Activity) =
any { it.get() === activity }
private fun Activity.weak() = WeakReference(this)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment