2016-09-16 5 views
0

Ich bekomme den folgenden Fehler ausgelöst von React Native. Ich bin mir ziemlich sicher, dass es mit einer benutzerdefinierten Ansicht verknüpft ist, die ich verwende.Native Ausnahme reaktivieren: Das angegebene Kind hat bereits einen Elternteil.

Die Ansicht wird von einem C++ - Code (über OpenGL) generiert, der zu einer ViewGroup hinzugefügt und dann in eine native React-Ansicht integriert wird. Wenn die App zum ersten Mal geladen wird, ist alles in Ordnung. Wenn sich jedoch einige Daten ändern, scheint React die Ansicht neu zu laden und eine neue Instanz der Ansicht zu erstellen. Ich überprüfe, ob die Ansicht einen Elternteil hat, und wenn ja, lösche sie, bevor die Ansicht zurückgegeben wird. Nachdem der Benutzer jedoch neue Daten auswählt, tritt der Absturz auf, sobald die Ansichten aktualisiert werden.

Der Viewmanager-Code ist wie folgt:

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; 
    } 

} 

.. und hier ist der Stack-Trace:

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) 

Antwort

0

ich geändert, wie die JuceBridge speichert Verweise auf Komponenten - Speicherung ComponentPeerView s statt der View das ist die JuceViewHolder.

(Siehe mein fork of JUCE)

ich dann die ComponentPeerView ‚s Eltern zugegriffen, die mein Problem gelöst:

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; 
} 
Verwandte Themen