Yes.
Yes.
Environment:
OS: macOS Sierra 10.12.6
Node: 8.4.0
Yarn: 1.3.2
Watchman: 4.9.0
Packages: (wanted => installed)
react-native: 0.50.1 => 0.50.1
react: 16.0.0 => 16.0.0
Target Platform: Android 7.1.1
<Surface> area becomes invisable;it should just look like same with the first render.
the <Surface> area becomes invisable;
the main just like below:
<Surface width={ 300 } height={ 200 }>
<Shape d={ new Path()
.moveTo(0, 0)
.lineTo(0, 200)
.lineTo(300, 200)
.lineTo(300, 0)
.close() } fill={ '#f00' } />
</Surface>
me too. if you refresh ui ,it good work. how did you solve it?
Same issues . I think the maintainers are have only iOS devices and don't want support android. I think they do work on react-native only because they likes write code on js for iOS.
Thanks for posting this! It looks like you may not be using the latest version of React Native, v0.53.0, released on January 2018. Can you make sure this issue can still be reproduced in the latest version?
I am going to close this, but please feel free to open a new issue if you are able to confirm that this is still a problem in v0.53.0 or newer.
I updated to React Native 0.53.3 and still have this issue.
I tried to call this.forceUpdate as a work around and still did not work.
em, what i face is ,when i use animated on Surface, like
const AniSurface = Animated.createAnimatedComponent(Surface)
<AniSurface style={{transform: [{translateX: this.state.aniTransX}]}}/>
when the animation start the Surface panel invisible, all dark like
but, when i open the dev menu, and click Toggle Inspector, the Surface visible again
=====UPDATE 2018.03.05=====
set style backgroundColor on the top View(not always top View, but must parent View), the Surface always visible
me too.
I call this.forceUpdate, But the situation is not improved.
Same here. We ended up changing component's key value to force remount on active app state change and device rotation (AppState and Dimensions event listeners).
I'm facing the same problem. I will probably use the same fix (like there https://github.com/bgryszko/react-native-circular-progress/commit/f198080ef269db0064ac5363de50a0ad98c3028a).
I don't get why this issue has been closed... it makes ReactNative ART on Android unreliable.
I am also having this problem, ended up using the AppState solution. This bug makes ART almost unusable on Android. I hope to investigate it a bit further next week when i have some spare time.
CC: @btegenbosch
I still have similar problems.
When will this problem be improved?
Also, what is the most effective solution? 🤔
Results from an internal investigation here:
From API level 25 onwards the hardware layer is deleted with the below call stack

Screen on -> TextureView's draw gets called --boolean createNewSurface = (mSurface == null); if (createNewSurface) { // Create a new SurfaceTexture for the layer. mSurface = new SurfaceTexture(false); nCreateNativeWindow(mSurface); } mLayer.setSurfaceTexture(mSurface);So, if there is a surface existing from before sleep, use that. A regular Textureview proceeds to draw on preexisting surface and has no problem.
In the case of ARTSurfaceView we are doing all the drawing here -
(Oh btw, Android says not to actually -
Subclasses of TextureView cannot do their own rendering with the {@link Canvas} object.)So, ARTSurfaceView is not aware of the whole sleep and destroy, there is no redraw after screen gets switched on and hence the blank screen.
It sounds like the best path forwards may be to switch from TextureView to SurfaceView since the latter appears intended for software drawing which is what we're doing (vs video/camera use cases recommended in TextureView docs).
It's not clear if we'll have time to work on this at FB soon but if someone in the community wants to try their hand at making the switch then that would be valuable towards getting this bug fixed.
cc @himabindugadupudi
Same issues , and I did a test on the latest ‘react-native-0.55’ that was not resolved. This problem directly led to my failure to use ART in my projects, but I found that a third-party framework 'react-native-svg' did not have this problem when used.
Why was this closed again? AIUI the bug still exists in the latest version ...
They write release notes say they have resolved it in 0.54.And I test the bug in react-native-0.54 ,0.55 ,still exists.
The commit fixing it had to be reverted due to another bug. Hopefully we will be able to land it again for a permanent fix.
@sophiebits Thank you so much for looking into it 🙌🏾 I love ART 😍
All workarounds seem to have some caveats, and best option seems to update react-native-art to use SurfaceViews instead. Force updates or app state changes are causing surface to disappear and re-appear after app resumes.
@himabindugadupudi your commit above seems to be in the right direction. I'd be happy to help to get this change into a PR
I think I solved this problem by modifying the implementation of ART on Android Native Code. The code changes very little.
Use View instead of SurfaceView or TextureView
Potential risk: Texurate used to be rendered in sub threads, and View is now in the main thread. But testing, it has almost no effect on rendering speed.
code:
com.facebook.react.views.art.ARTSurfaceView.java :
public class ARTSurfaceView extends View {
private ARTSurfaceViewShadowNode.OnDrawCallback onDrawCallback;
public ARTSurfaceView(Context context) {
super(context);
// setOpaque(false);
}
public void setOnDrawCallback(ARTSurfaceViewShadowNode.OnDrawCallback onDrawCallback) {
this.onDrawCallback = onDrawCallback;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (onDrawCallback != null) {
onDrawCallback.drawOutput(canvas);
}
}
}
com.facebook.react.views.art.ARTSurfaceViewShadowNode.java :
public class ARTSurfaceViewShadowNode extends LayoutShadowNode {
private @Nullable Integer mBackgroundColor;
@ReactProp(name = ViewProps.BACKGROUND_COLOR, customType = "Color")
public void setBackgroundColor(Integer color) {
mBackgroundColor = color;
markUpdated();
}
@Override
public boolean isVirtual() {
return false;
}
@Override
public boolean isVirtualAnchor() {
return true;
}
@Override
public void onCollectExtraUpdates(UIViewOperationQueue uiUpdater) {
super.onCollectExtraUpdates(uiUpdater);
// drawOutput();
uiUpdater.enqueueUpdateExtraData(getReactTag(), this);
}
public interface OnDrawCallback {
void drawOutput(Canvas canvas);
}
public OnDrawCallback getOnDrawCallback() {
return onDrawCallback;
}
private OnDrawCallback onDrawCallback = new OnDrawCallback() {
@Override
public void drawOutput(Canvas canvas) {
ARTSurfaceViewShadowNode.this.drawOutput(canvas);
}
};
private void drawOutput(Canvas canvas) {
// if (mSurface == null || !mSurface.isValid()) {
// markChildrenUpdatesSeen(this);
// return;
// }
try {
canvas.drawColor(Color.TRANSPARENT);
if (mBackgroundColor != null) {
canvas.drawColor(mBackgroundColor);
}
Paint paint = new Paint();
for (int i = 0; i < getChildCount(); i++) {
ARTVirtualNode child = (ARTVirtualNode) getChildAt(i);
child.draw(canvas, paint, 1f);
child.markUpdateSeen();
}
// mSurface.unlockCanvasAndPost(canvas);
} catch (IllegalArgumentException | IllegalStateException e) {
FLog.e(ReactConstants.TAG, e.getClass().getSimpleName() + " in Surface.unlockCanvasAndPost");
}
}
}
com.facebook.react.views.art.ARTSurfaceViewManager.java :
...
@Override
public void updateExtraData(ARTSurfaceView root, Object extraData) {
// root.getHolder().addCallback((ARTSurfaceViewShadowNode) extraData);
// root.getHolder().addCallback((ARTSurfaceViewShadowNode) extraData);
root.setOnDrawCallback(((ARTSurfaceViewShadowNode) extraData).getOnDrawCallback());
}
...
How to set click event of shape area in react native ?
I need write click event of particular Shape which draw using react native ART. How can i achieve this ?
can you please share your ideas or thought on this so can i worked on it.
sectionAngles.map(section => (
<Group>
<TouchableWithoutFeedback
onPress={this.bindCallBackClick}>
<View>
<Shape
key={section.index}
d={path(section)}
fill={section.data.color}
strokeWidth={1} />
<ART.Text font={{ fontFamily: 'Helvetica Neue', fontSize: 20, }}
fill="#000"
x={path.centroid(section)[0]}
y={path.centroid(section)[1]}
ellipsizeMode={"middle"}
alignment="center"
>{section.data.itemName}</ART.Text>
</View></TouchableWithoutFeedback>
</Group>
))
Same problem,How to solve this?
Same problem here.
Hello everyone I created a pull request that fix this issue, if possible could you guys take a look? Thank you very much #22624
Hello, are there any updates on this? Is it planned for the next release of React Native or would it be better to make a fork and fix it there?
We just merged the PR that is supposed to fix this issue, to be shipped with 0.61.
While 0.61 isn't released yet, I've done a workaround solution that isn't perfect but works.
I've created a Surface class that updates it key when going foreground, then React Native lifecycle will destroy and create the instance.
import React from 'react';
import {
AppState,
ART,
ARTSurfaceProps,
} from 'react-native';
const { Surface: RNSurface } = ART;
const uuid = () => Math.random().toString(36).substring(2) + (new Date()).getTime().toString(36);
export default class Surface extends React.Component<ARTSurfaceProps> {
constructor(props) {
super(props);
const propKey = props.key || 'surface';
this.state = {
key: `${propKey}-${uuid()}`,
propKey,
appState: AppState.currentState,
};
}
componentDidMount() {
AppState.addEventListener('change', this.handleAppStateChange);
}
componentWillUnmount() {
AppState.removeEventListener('change', this.handleAppStateChange);
}
static getDerivedStateFromProps(nextProps, prevState) {
const propKey = nextProps.key || 'surface';
if (propKey !== prevState.propKey) {
return {
key: `${propKey}-${uuid()}`,
propKey,
};
}
return null;
}
handleAppStateChange = (nextAppState) => {
const {
appState,
propKey,
} = this.state;
if (appState.match(/inactive|background/) && nextAppState === 'active') {
this.setState({ appState: nextAppState, key: `${propKey}-${uuid()}` });
} else if (appState === 'active' && nextAppState.match(/inactive|background/)) {
this.setState({ appState: nextAppState });
}
};
render() {
const { key } = this.state;
return (
<RNSurface
key={key}
{...this.props}
/>
);
}
}
When will 0.61 be released?
@baragatti, It worked. Thank you.
While 0.61 isn't released yet, I've done a workaround solution that isn't perfect but works.
I've created a Surface class that updates it key when going foreground, then React Native lifecycle will destroy and create the instance.import React from 'react'; import { AppState, ART, ARTSurfaceProps, } from 'react-native'; const { Surface: RNSurface } = ART; const uuid = () => Math.random().toString(36).substring(2) + (new Date()).getTime().toString(36); export default class Surface extends React.Component<ARTSurfaceProps> { constructor(props) { super(props); const propKey = props.key || 'surface'; this.state = { key: `${propKey}-${uuid()}`, propKey, appState: AppState.currentState, }; } componentDidMount() { AppState.addEventListener('change', this.handleAppStateChange); } componentWillUnmount() { AppState.removeEventListener('change', this.handleAppStateChange); } static getDerivedStateFromProps(nextProps, prevState) { const propKey = nextProps.key || 'surface'; if (propKey !== prevState.propKey) { return { key: `${propKey}-${uuid()}`, propKey, }; } return null; } handleAppStateChange = (nextAppState) => { const { appState, propKey, } = this.state; if (appState.match(/inactive|background/) && nextAppState === 'active') { this.setState({ appState: nextAppState, key: `${propKey}-${uuid()}` }); } else if (appState === 'active' && nextAppState.match(/inactive|background/)) { this.setState({ appState: nextAppState }); } }; render() { const { key } = this.state; return ( <RNSurface key={key} {...this.props} /> ); } }
Thanks !!!!!! It works . you did help a lot
Most helpful comment
I think I solved this problem by modifying the implementation of ART on Android Native Code. The code changes very little.
Use View instead of SurfaceView or TextureView
Potential risk: Texurate used to be rendered in sub threads, and View is now in the main thread. But testing, it has almost no effect on rendering speed.
code:
com.facebook.react.views.art.ARTSurfaceView.java :
com.facebook.react.views.art.ARTSurfaceViewShadowNode.java :
com.facebook.react.views.art.ARTSurfaceViewManager.java :