The ART '<Surface>' becomes invisible in Android (#22624)
Summary: Hello Everyone, this series of commits helps to fix problems related to ART on Android. The main problem in here is that the ART components would disappear if the user turns off the screen and then turn it on again. It's important to note that this behaviour only occurs after Android N (7.1 or higher). Pull Request resolved: https://github.com/facebook/react-native/pull/22624 Differential Revision: D15122573 Pulled By: cpojer fbshipit-source-id: e7fb8b9280b4c52562e3d0c1a89759d4d31cd53d
This commit is contained in:
Родитель
110a382b59
Коммит
20b09e4c45
|
@ -60,7 +60,8 @@ public class ARTSurfaceViewManager extends
|
|||
|
||||
@Override
|
||||
public void updateExtraData(ARTSurfaceView root, Object extraData) {
|
||||
root.setSurfaceTextureListener((ARTSurfaceViewShadowNode) extraData);
|
||||
ARTSurfaceViewShadowNode shadowNode = (ARTSurfaceViewShadowNode) extraData;
|
||||
shadowNode.setupSurfaceTextureListener(root);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -16,6 +16,7 @@ import android.view.Surface;
|
|||
import android.graphics.PorterDuff;
|
||||
import android.graphics.SurfaceTexture;
|
||||
import android.view.TextureView;
|
||||
import android.os.Build;
|
||||
|
||||
import com.facebook.common.logging.FLog;
|
||||
import com.facebook.react.common.ReactConstants;
|
||||
|
@ -23,13 +24,15 @@ import com.facebook.react.uimanager.LayoutShadowNode;
|
|||
import com.facebook.react.uimanager.UIViewOperationQueue;
|
||||
import com.facebook.react.uimanager.ReactShadowNode;
|
||||
import com.facebook.react.uimanager.ViewProps;
|
||||
import com.facebook.react.uimanager.ThemedReactContext;
|
||||
import com.facebook.react.uimanager.annotations.ReactProp;
|
||||
import com.facebook.react.bridge.LifecycleEventListener;
|
||||
|
||||
/**
|
||||
* Shadow node for ART virtual tree root - ARTSurfaceView
|
||||
*/
|
||||
public class ARTSurfaceViewShadowNode extends LayoutShadowNode
|
||||
implements TextureView.SurfaceTextureListener {
|
||||
implements TextureView.SurfaceTextureListener, LifecycleEventListener {
|
||||
|
||||
private @Nullable Surface mSurface;
|
||||
|
||||
|
@ -54,11 +57,11 @@ public class ARTSurfaceViewShadowNode extends LayoutShadowNode
|
|||
@Override
|
||||
public void onCollectExtraUpdates(UIViewOperationQueue uiUpdater) {
|
||||
super.onCollectExtraUpdates(uiUpdater);
|
||||
drawOutput();
|
||||
drawOutput(false);
|
||||
uiUpdater.enqueueUpdateExtraData(getReactTag(), this);
|
||||
}
|
||||
|
||||
private void drawOutput() {
|
||||
private void drawOutput(boolean markAsUpdated) {
|
||||
if (mSurface == null || !mSurface.isValid()) {
|
||||
markChildrenUpdatesSeen(this);
|
||||
return;
|
||||
|
@ -75,19 +78,31 @@ public class ARTSurfaceViewShadowNode extends LayoutShadowNode
|
|||
for (int i = 0; i < getChildCount(); i++) {
|
||||
ARTVirtualNode child = (ARTVirtualNode) getChildAt(i);
|
||||
child.draw(canvas, paint, 1f);
|
||||
child.markUpdateSeen();
|
||||
if (markAsUpdated) {
|
||||
child.markUpdated();
|
||||
} else {
|
||||
child.markUpdateSeen();
|
||||
}
|
||||
}
|
||||
|
||||
if (mSurface == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
mSurface.unlockCanvasAndPost(canvas);
|
||||
} catch (IllegalArgumentException | IllegalStateException e) {
|
||||
FLog.e(ReactConstants.TAG, e.getClass().getSimpleName() + " in Surface.unlockCanvasAndPost");
|
||||
}
|
||||
}
|
||||
|
||||
public void setupSurfaceTextureListener(ARTSurfaceView surfaceView) {
|
||||
SurfaceTexture surface = surfaceView.getSurfaceTexture();
|
||||
surfaceView.setSurfaceTextureListener(this);
|
||||
if (surface != null && mSurface == null) {
|
||||
mSurface = new Surface(surface);
|
||||
drawOutput(true);
|
||||
}
|
||||
}
|
||||
|
||||
private void markChildrenUpdatesSeen(ReactShadowNode shadowNode) {
|
||||
for (int i = 0; i < shadowNode.getChildCount(); i++) {
|
||||
ReactShadowNode child = shadowNode.getChildAt(i);
|
||||
|
@ -96,15 +111,42 @@ public class ARTSurfaceViewShadowNode extends LayoutShadowNode
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setThemedContext(ThemedReactContext themedContext) {
|
||||
super.setThemedContext(themedContext);
|
||||
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.N) {
|
||||
themedContext.addLifecycleEventListener(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
super.dispose();
|
||||
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.N) {
|
||||
getThemedContext().removeLifecycleEventListener(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onHostResume() {
|
||||
drawOutput(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onHostPause() {}
|
||||
|
||||
@Override
|
||||
public void onHostDestroy() {}
|
||||
|
||||
@Override
|
||||
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
|
||||
mSurface = new Surface(surface);
|
||||
drawOutput();
|
||||
drawOutput(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
|
||||
surface.release();
|
||||
mSurface.release();
|
||||
mSurface = null;
|
||||
return true;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче