Io.kt
TLDR
This file provides implementation for executing tasks on the IO thread and updating the UI from the IO thread.
Methods
execute
This method executes the given block of code on the IO thread.
execute(view: View, block: OnIo.() -> Unit)
This method executes the given block of code on the IO thread and updates the UI from the IO thread.
Classes
None
package leakcanary.internal.activity.db
import android.view.View
import leakcanary.internal.activity.db.Io.OnIo
import leakcanary.internal.navigation.onScreenExiting
import leakcanary.internal.friendly.checkMainThread
import leakcanary.internal.friendly.mainHandler
import java.util.concurrent.Executors
internal object Io {
private val serialExecutor =
Executors.newSingleThreadExecutor { runnable -> Thread(runnable, "LeakCanary-Activity-DB") }
fun interface OnIo {
fun updateUi(updateUi: View.() -> Unit)
}
private class IoContext : OnIo {
var updateUi: (View.() -> Unit)? = null
override fun updateUi(updateUi: View.() -> Unit) {
this.updateUi = updateUi
}
}
fun execute(block: () -> Unit) {
serialExecutor.execute(block)
}
fun execute(
view: View,
block: OnIo.() -> Unit
) {
checkMainThread()
val viewWrapper: VolatileObjectRef<View> = VolatileObjectRef(view)
view.onScreenExiting {
viewWrapper.element = null
}
serialExecutor.execute backgroundExecute@{
if (viewWrapper.element == null) {
return@backgroundExecute
}
val context = IoContext()
block(context)
val updateUi = context.updateUi
if (viewWrapper.element != null && updateUi != null) {
mainHandler.post mainThreadPost@{
val attachedView = viewWrapper.element ?: return@mainThreadPost
updateUi(attachedView)
}
}
}
}
/**
* Similar to kotlin.jvm.internal.Ref.ObjectRef but volatile
*/
private class VolatileObjectRef<T>(
@Volatile
var element: T? = null
)
}
internal fun View.executeOnIo(block: OnIo.() -> Unit) {
Io.execute(this, block)
}