Skip to content

Images intermittently disappear on Android #20898

Closed
@getaaron

Description

@getaaron

Images intermittently disappear on Android

Several issues reported in #13600 which was closed due to being stale but the issue still persists

Using RN 0.55 (can't use 0.56 due to babel 7 and jest mock incompatibilities)

Note / Possible Workaround

In my testing, this issue only occurs when importing images like:

<Image source={require('./my-icon.png')} />

But if I import via:

import myIcon from './my-icon.png';

then it works fine.

See the blog post Quick Tip: Images in React-Native on Android Not Loading for more on this.

Environment

Scanning folders for symlinks in /Users/aaronbrager/[REDACTED]/node_modules (17ms)

Environment:
OS: macOS 10.14
Node: 10.8.0
Yarn: 1.9.4
npm: 6.2.0
Watchman: 4.9.0
Xcode: Xcode 9.4.1 Build version 9F2000
Android Studio: 3.0 AI-171.4443003

Packages: (wanted => installed)
react: 16.3.1 => 16.3.1
react-native: 0.55.4 => 0.55.4

[skip envinfo]

Possible cause

fresco has a cache pool for decoded bitmap, with a default size determined by the available runtime memory:

https://github.com/facebook/fresco/blob/3ccf021877571cc66c1cf28ecc82788f83579ad3/imagepipeline/src/main/java/com/facebook/imagepipeline/memory/BitmapCounterProvider.java#L32-L39

When the amount of memory is insufficient it throws an exception:

https://github.com/facebook/fresco/blob/8731cca73e5a4bd44387657dacd1f4562e549854/imagepipeline/src/main/java/com/facebook/imagepipeline/memory/BasePool.java#L237-L245

When this happens, React Native eats the exception and fails silently (see line 71):

@Override
public void onProducerFinishWithSuccess(
String requestId,
String producerName,
Map<String, String> extraMap) {
if (!Systrace.isTracing(Systrace.TRACE_TAG_REACT_FRESCO)) {
return;
}
if (mProducerID.containsKey(requestId)) {
Pair<Integer, String> entry = mProducerID.get(requestId);
Systrace.endAsyncSection(
Systrace.TRACE_TAG_REACT_FRESCO,
entry.second,
entry.first);
mProducerID.remove(requestId);
}
}
@Override
public void onProducerFinishWithFailure(
String requestId,
String producerName,
Throwable throwable,
Map<String, String> extraMap) {
if (!Systrace.isTracing(Systrace.TRACE_TAG_REACT_FRESCO)) {
return;
}
if (mProducerID.containsKey(requestId)) {
Pair<Integer, String> entry = mProducerID.get(requestId);
Systrace.endAsyncSection(
Systrace.TRACE_TAG_REACT_FRESCO,
entry.second,
entry.first);
mProducerID.remove(requestId);
}
}

Instead of failing silently, React Native should do something (increase memory, free resources, clear cache… not sure) to ensure that the image being rendered appears.

Initial research done by @fatfatson (see #13600 (comment))

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions