Checklist
- My animation doesn't use any unsupported features. ✅
- I know what part of my animation doesn't work. ✅
- have created a simplified reproduction below. ✅
- An AEP file is not applicable because this reproduces the ZIP image-asset loading behavior directly.✅
When a ZIP / .lottie animation defines multiple image asset IDs that reference the same physical image filename, only one asset receives the decoded bitmap on Android.
For example:
{
"assets": [
{ "id": "image_a", "w": 100, "h": 100, "u": "images/", "p": "shared.png" },
{ "id": "image_b", "w": 100, "h": 100, "u": "images/", "p": "shared.png" }
]
}
The ZIP contains one physical file:
Both assets are independently addressable by ID but intentionally reuse the same image data. Web and iOS renderers can reuse the file for both assets. Android populates only the first matching LottieImageAsset, so layers referencing the remaining IDs render without an image.
The issue is in LottieCompositionFactory.fromZipStreamSyncInternal(). It iterates over decoded ZIP files and calls findImageAssetForFileName(), which returns immediately after finding the first asset with the matching filename.
Expected behavior
The decoded image should be assigned to every LottieImageAsset whose filename matches the ZIP entry. Assets with the same declared dimensions should be able to reuse the same bitmap. If matching assets declare different dimensions, the bitmap should be scaled once per distinct size.
What version of Lottie did you test this on?
Current master at 05ea92e90381eb8a8ae06855ea2b74f322bebbec.
What version of Android did you test this on?
This is not Android-version-specific. It occurs in the ZIP parsing and bitmap assignment path before rendering.
Steps To Reproduce
- Create a Lottie JSON with two image asset IDs whose
p fields both equal shared.png.
- Add two image layers, one referencing each asset ID.
- Package the JSON and a single
images/shared.png file in a ZIP / .lottie file.
- Load the animation using the Android ZIP loading path.
- Observe that only one image layer has a bitmap.
Additional context
The single-result lookup is here:
|
@Nullable |
|
private static LottieImageAsset findImageAssetForFileName(LottieComposition composition, String fileName) { |
|
for (LottieImageAsset asset : composition.getImages().values()) { |
|
if (asset.getFileName().equals(fileName)) { |
|
return asset; |
|
} |
|
} |
|
return null; |
|
} |
Checklist
When a ZIP /
.lottieanimation defines multiple image asset IDs that reference the same physical image filename, only one asset receives the decoded bitmap on Android.For example:
{ "assets": [ { "id": "image_a", "w": 100, "h": 100, "u": "images/", "p": "shared.png" }, { "id": "image_b", "w": 100, "h": 100, "u": "images/", "p": "shared.png" } ] }The ZIP contains one physical file:
Both assets are independently addressable by ID but intentionally reuse the same image data. Web and iOS renderers can reuse the file for both assets. Android populates only the first matching
LottieImageAsset, so layers referencing the remaining IDs render without an image.The issue is in
LottieCompositionFactory.fromZipStreamSyncInternal(). It iterates over decoded ZIP files and callsfindImageAssetForFileName(), which returns immediately after finding the first asset with the matching filename.Expected behavior
The decoded image should be assigned to every
LottieImageAssetwhose filename matches the ZIP entry. Assets with the same declared dimensions should be able to reuse the same bitmap. If matching assets declare different dimensions, the bitmap should be scaled once per distinct size.What version of Lottie did you test this on?
Current
masterat05ea92e90381eb8a8ae06855ea2b74f322bebbec.What version of Android did you test this on?
This is not Android-version-specific. It occurs in the ZIP parsing and bitmap assignment path before rendering.
Steps To Reproduce
pfields both equalshared.png.images/shared.pngfile in a ZIP /.lottiefile.Additional context
The single-result lookup is here:
lottie-android/lottie/src/main/java/com/airbnb/lottie/LottieCompositionFactory.java
Lines 791 to 799 in 05ea92e