Skip to content

Commit 3bf54ec

Browse files
committed
feat: android implementation of RiveImage
1 parent 90b6473 commit 3bf54ec

3 files changed

Lines changed: 77 additions & 1 deletion

File tree

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package com.margelo.nitro.rive
2+
3+
import androidx.annotation.Keep
4+
import app.rive.runtime.kotlin.core.RiveRenderImage
5+
import com.facebook.proguard.annotations.DoNotStrip
6+
7+
@Keep
8+
@DoNotStrip
9+
class HybridRiveImage(
10+
val renderImage: RiveRenderImage,
11+
private val dataSize: Int
12+
) : HybridRiveImageSpec() {
13+
14+
override val byteSize: Double
15+
get() = dataSize.toDouble()
16+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package com.margelo.nitro.rive
2+
3+
import androidx.annotation.Keep
4+
import app.rive.runtime.kotlin.core.RiveRenderImage
5+
import com.facebook.proguard.annotations.DoNotStrip
6+
import com.margelo.nitro.core.Promise
7+
import kotlinx.coroutines.Dispatchers
8+
import kotlinx.coroutines.withContext
9+
import java.net.HttpURLConnection
10+
import java.net.URL
11+
12+
@Keep
13+
@DoNotStrip
14+
class HybridRiveImageFactory : HybridRiveImageFactorySpec() {
15+
16+
override fun loadFromURLAsync(url: String): Promise<HybridRiveImageSpec> {
17+
return Promise.async {
18+
try {
19+
val (imageData, dataSize) = withContext(Dispatchers.IO) {
20+
val urlObj = URL(url)
21+
val connection = urlObj.openConnection() as HttpURLConnection
22+
23+
try {
24+
connection.requestMethod = "GET"
25+
val statusCode = connection.responseCode
26+
27+
if (statusCode !in 200..299) {
28+
throw Exception("Failed to load image from URL: $url (status: $statusCode)")
29+
}
30+
31+
val bytes = connection.inputStream.use { it.readBytes() }
32+
Pair(bytes, bytes.size)
33+
} finally {
34+
connection.disconnect()
35+
}
36+
}
37+
38+
val renderImage = RiveRenderImage.fromEncoded(imageData)
39+
40+
HybridRiveImage(renderImage, dataSize)
41+
} catch (e: Exception) {
42+
throw Exception("Failed to load image from URL: $url - ${e.message}")
43+
}
44+
}
45+
}
46+
}

android/src/main/java/com/margelo/nitro/rive/ReferencedAssetLoader.kt

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,14 +181,28 @@ class ReferencedAssetLoader {
181181

182182
private fun processAssetBytes(bytes: ByteArray, asset: FileAsset) {
183183
when (asset) {
184-
is ImageAsset -> asset.image = RiveRenderImage.make(bytes)
184+
is ImageAsset -> asset.image = RiveRenderImage.fromEncoded(bytes)
185185
is FontAsset -> asset.font = RiveFont.make(bytes)
186186
is AudioAsset -> asset.audio = RiveAudio.make(bytes)
187187
}
188188
}
189189

190+
private fun handlePreloadedImage(image: HybridRiveImageSpec, asset: FileAsset) {
191+
if (asset is ImageAsset && image is HybridRiveImage) {
192+
asset.image = image.renderImage
193+
}
194+
}
195+
190196
private fun loadAsset(assetData: ResolvedReferencedAsset, asset: FileAsset, context: Context): Deferred<Unit> {
191197
val deferred = CompletableDeferred<Unit>()
198+
199+
// Check for pre-loaded image first
200+
if (assetData.image != null) {
201+
handlePreloadedImage(assetData.image, asset)
202+
deferred.complete(Unit)
203+
return deferred
204+
}
205+
192206
val listener: (ByteArray?) -> Unit = { bytes ->
193207
if (bytes != null) {
194208
processAssetBytes(bytes, asset)

0 commit comments

Comments
 (0)