ianrumac
10/27/2019, 12:07 PMContainer{
val state = +model{ NetworkImagemodel(bitmap: null); } // this is a @Model annotated data class
glideBitmapReady(src,context) {
state.bitmap = it //this is callback from Glide's onResourceReady
}
onCommit(state) {
println("Loaded)"
}
}
I get a IllegalStateException: Not in a frame
pointing to the change of state model (state.bitmap = it //this is callback from Glide's onResourceReady
)Andrey Kulikov
10/27/2019, 12:11 PMianrumac
10/27/2019, 12:13 PMGlide.with( context).asBitmap().load(src)
.addListener(object :
RequestListener<Bitmap> {
override fun onLoadFailed(
e: GlideException?,
model: Any?,
target: Target<Bitmap>?,
isFirstResource: Boolean
): Boolean {
e!!.printStackTrace()
return false
}
override fun onResourceReady(
resource: Bitmap?,
_model: Any?,
target: Target<Bitmap>?,
dataSource: DataSource?,
isFirstResource: Boolean
): Boolean {
callback(resource)
return true
}
}).preload()
ianrumac
10/27/2019, 12:16 PMianrumac
10/27/2019, 12:30 PMianrumac
10/27/2019, 12:31 PMLeland Richardson [G]
10/27/2019, 2:57 PMLeland Richardson [G]
10/27/2019, 2:57 PMLeland Richardson [G]
10/27/2019, 2:58 PMglideBitmapReady
function, as you noticed, will run too oftenLeland Richardson [G]
10/27/2019, 2:58 PMLeland Richardson [G]
10/27/2019, 2:59 PMonCommit
effect is a way to run code when compose actually applies the changes to the UI, and only when some number of inputs have changed (like memo)Leland Richardson [G]
10/27/2019, 2:59 PMLeland Richardson [G]
10/27/2019, 2:59 PMfun glideBitmapReady(src: String) = effectOf<Bitmap?> {
val result = +state<Bitmap> { null }
val context = +ambient(AmbientContext)
+onPreCommit(src) {
val listener = object : RequestListener<Bitmap> {
override fun onLoadFailed(
e: GlideException?,
model: Any?,
target: Target<Bitmap>?,
isFirstResource: Boolean
): Boolean {
e!!.printStackTrace()
return false
}
override fun onResourceReady(
resource: Bitmap?,
_model: Any?,
target: Target<Bitmap>?,
dataSource: DataSource?,
isFirstResource: Boolean
): Boolean {
result.value = resource
return true
}
}
val glide = Glide
.with(context)
.asBitmap()
.load(src)
.addListener(listener)
.preload()
onDispose {
glide.removeListener(listener)
}
}
result.value
}
Leland Richardson [G]
10/27/2019, 3:00 PM= effectOf<Bitmap?>
would just turn into : Bitmap?
and all of the pluses would go awayLeland Richardson [G]
10/27/2019, 3:01 PMonPreCommit
when the src
string changes. this means that things will properly update if you change the src stringLeland Richardson [G]
10/27/2019, 3:01 PMremoveListener
was an API that exists, but let me know if it doesntLeland Richardson [G]
10/27/2019, 3:02 PMonDispose
here with the removeListener
call, which ensures that as the src string changes, I clean up any old requests that had been set up from earlier versionsLeland Richardson [G]
10/27/2019, 3:03 PMvar bitmap = +glideBitmapReady(src)
Leland Richardson [G]
10/27/2019, 3:05 PMIllegalStateException: Not in a frame
was because you were mutating the model in a different thread. This is totally allowed, but you have to do a little bit of extra work. In this case, you need to open up a model transaction and commit it.
I’m not in a place to look up the exact API, but I believe if you look in androidx.compose.frames
it will be something like
open {
myModel.property = newValue
commit()
}
ianrumac
10/27/2019, 3:14 PMLeland Richardson [G]
10/27/2019, 3:16 PMianrumac
10/27/2019, 3:18 PMopen
tip, I assumed that I was out of the UI scope/thread when getting the exception, and started going through `Frames’ to figure out what was going on but couldn’t really wrap my head around it, now it’s more obvious.Leland Richardson [G]
10/27/2019, 3:19 PMLeland Richardson [G]
10/27/2019, 3:19 PMianrumac
10/27/2019, 3:22 PMLeland Richardson [G]
10/27/2019, 3:22 PMeffectOf
for nowLeland Richardson [G]
10/27/2019, 3:22 PMframe
doesn’t actually correspond to the UI’s sense of frame
hereianrumac
10/27/2019, 3:23 PMLeland Richardson [G]
10/27/2019, 3:23 PMLeland Richardson [G]
10/27/2019, 3:24 PMLeland Richardson [G]
10/27/2019, 3:25 PMLeland Richardson [G]
10/27/2019, 3:25 PMLeland Richardson [G]
10/27/2019, 3:25 PMLeland Richardson [G]
10/27/2019, 3:26 PMLeland Richardson [G]
10/27/2019, 3:26 PMLeland Richardson [G]
10/27/2019, 3:26 PMLeland Richardson [G]
10/27/2019, 3:26 PMianrumac
10/27/2019, 3:28 PMianrumac
10/27/2019, 3:29 PMModel
, transaction does fit betterianrumac
10/27/2019, 3:30 PMLeland Richardson [G]
10/27/2019, 3:32 PMianrumac
10/27/2019, 3:49 PM