我收到React Native触发的以下错误。我很确定它与我正在使用的自定义视图相关联。
视图由一些C ++代码(通过OpenGL)生成,该代码被添加到ViewGroup
,然后合并到React Native视图中。应用程序第一次加载,一切都很好。但是,当某些数据发生变化时,似乎React想要重新加载视图,并创建一个新的视图实例。我正在检查视图是否有父视图,如果是,请在返回视图之前将其删除。但是,在用户选择新数据之后,就像视图即将更新一样,崩溃也会发生。
ViewManager代码如下:
public class ReactJuceViewManager extends SimpleViewManager<JuceViewHolder> {
public static final String REACT_CLASS = "ReactJuceView";
private ReactApplicationContext reactContext;
public ReactJuceViewManager(ReactApplicationContext reactContext)
{
super();
this.reactContext = reactContext;
}
@Override
public String getName()
{
return REACT_CLASS;
}
@Override
protected JuceViewHolder createViewInstance(ThemedReactContext themedReactContext) {
JuceBridge juceBridge = JuceBridge.getInstance();
//JuceBridge manages the a HashMap of `JuceViewHolder`s, never deleting them once created
Log.d("ReactJuceViewManager", "createViewInstance");
JuceViewHolder v = juceBridge.getViewForComponent("Tuner", themedReactContext);
Log.d("JuceViewHolder", v.getTag().toString());
ViewGroup parent = (ViewGroup) v.getParent();
if (parent != null)
{
Log.d("ReactJuceViewManager", "JuceViewHolder parent: " + v.getParent().toString());
// Remove from parent
Log.i("ReactJuceViewManager", "Removing JuceViewHolder instance from previous parent");
parent.removeView(v);
}
else
{
Log.d("ReactJuceViewManager", "JuceViewHolder parent: null");
}
return v;
}
}
..这里是堆栈跟踪:
E/unknown:React: Exception in native call from JS
java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
at android.view.ViewGroup.addViewInner(ViewGroup.java:4309)
at android.view.ViewGroup.addView(ViewGroup.java:4145)
at android.view.ViewGroup.addView(ViewGroup.java:4086)
at com.facebook.react.views.view.ReactViewManager.addView(ReactViewManager.java:196)
at com.facebook.react.views.view.ReactViewManager.addView(ReactViewManager.java:39)
at com.facebook.react.uimanager.NativeViewHierarchyManager.manageChildren(NativeViewHierarchyManager.java:384)
at com.facebook.react.uimanager.UIViewOperationQueue$ManageChildrenOperation.execute(UIViewOperationQueue.java:175)
at com.facebook.react.uimanager.UIViewOperationQueue$2.run(UIViewOperationQueue.java:782)
at com.facebook.react.uimanager.UIViewOperationQueue.flushPendingBatches(UIViewOperationQueue.java:829)
at com.facebook.react.uimanager.UIViewOperationQueue.access$1500(UIViewOperationQueue.java:44)
at com.facebook.react.uimanager.UIViewOperationQueue$DispatchUIFrameCallback.doFrameGuarded(UIViewOperationQueue.java:868)
at com.facebook.react.uimanager.GuardedChoreographerFrameCallback.doFrame(GuardedChoreographerFrameCallback.java:32)
at com.facebook.react.uimanager.ReactChoreographer$ReactChoreographerDispatcher.doFrame(ReactChoreographer.java:131)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:856)
at android.view.Choreographer.doCallbacks(Choreographer.java:670)
at android.view.Choreographer.doFrame(Choreographer.java:603)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:844)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
答案 0 :(得分:0)
我更改了JuceBridge
存储对组件的引用的方式 - 存储ComponentPeerView
而不是View
JuceViewHolder
。
(参见我的fork of JUCE)
然后我访问了解决了我的问题的ComponentPeerView
家长:
protected ReactJuceView createViewInstance(ThemedReactContext themedReactContext) {
JuceBridge juceBridge = JuceBridge.getInstance();
juceBridge.setActivityContext(themedReactContext);
ReactJuceView v = new ReactJuceView(themedReactContext);
JuceBridge.ComponentPeerView componentPeerView = juceBridge.getPeerViewForComponent("MainComponent");
if (componentPeerView != null) {
Log.d ("ReactJuceViewManager", "Got componentPeerView");
ViewGroup parent = (ViewGroup) componentPeerView.getParent();
if (parent != null) {
parent.removeView(componentPeerView);
}
v.addView(componentPeerView);
Log.d( "ReactJuceViewManager", "About to attachOpenGlContext");
MainActivity.attachOpenGLContext("MainComponent");
}
else
Log.d("ReactJuceViewManager", "componentPeerView is null");
return v;
}
答案 1 :(得分:0)
我遇到了类似的问题,并且通过删除自定义视图的父级(如果该视图已经存在)使其起作用。
您可能应该在createViewInstance上返回一个新组件。
static CustomView customView;
@Override
public CustomView createViewInstance(@NonNull ThemedReactContext reactContext) {
if (customView == null) {
customView = new CustomView(reactContext);
} else {
ViewGroup parent = (ViewGroup) customView.getParent();
if (parent != null) {
parent.removeView(customView);
}
}
return customView;
}