2016-03-31 8 views
6

Come consigliato nei documenti, ho spostato un lungo codice di recupero dei dati in un modulo nativo per liberare il thread JS, ma osservo che questo sta ancora bloccando l'interfaccia utente. Perché è questo e cosa posso fare per evitarlo?Perché questa chiamata a un modulo nativo reattivo blocca l'interfaccia utente?

Il modulo nativo viene chiamato da JS come così:

MyNativeModule.fetch(path).then(data => dispatchData(data)) 

Il metodo nativo simile a questa (si utilizza l'Android Firebase SDK):

@ReactMethod 
public void fetch(final String path, final Promise promise) { 
    root.child(path).addListenerForSingleValueEvent(new ValueEventListener() { 
     @Override 
     public void onDataChange(DataSnapshot snapshot) { 
      if (snapshot.exists()) { 
       promise.resolve(castSnapshot(snapshot)); 
      } else { 
       promise.resolve(null); 
      } 
     } 
     @Override 
     public void onCancelled(FirebaseError firebaseError) { 
      promise.reject(firebaseError.getMessage()); 
     } 
    } 
} 

Il metodo castSnapshot converte il Firebase DataSnapshot oggetto in un WriteableMap. Posso condividere l'implementazione se ciò è utile.

Quello che ho osservato è che anche se sostituisco promise.resolve(castSnapshot(snapshot)); per castSnapshot(snapshot); promise.resolve(null);, la chiamata sta bloccando l'interfaccia utente: quindi non sta inviando i dati sul ponte che è il colpevole. Se la quantità di dati è elevata, l'operazione castSnapshot può richiedere un po 'di tempo e questo è chiaramente il blocco.

Anche se questo codice è di lunga durata, non è necessario spostarlo in un modulo nativo per liberare l'interfaccia utente? Cosa non capisco di questo?

Molte grazie.

+1

Ho lo stesso problema. Pensavo che i moduli nativi funzionassero su un thread diverso, tuttavia sembra che non lo faccia. –

+2

@RomShiri sì ... penso che se vogliamo utilizzare i moduli nativi per motivi perfetti dobbiamo gestire noi stessi il threading. Dai documenti: "I moduli nativi non dovrebbero avere alcuna ipotesi su quale thread vengono chiamati su [...] Se è richiesta una chiamata di blocco, il lavoro pesante deve essere inviato a un thread di lavoro gestito internamente e qualsiasi callback distribuito da Là." – VonD

+0

ho scoperto lo stesso. L'approccio di Ryans era necessario. – itinance

risposta

3

Provare avvolgendo la linea root.child in una nuova istanza Thread, in questo modo:

@ReactMethod 
public void fetch(final String path, final Promise promise) { 
    new Thread(new Runnable() { 
     public void run() { 
      root.child(path)... 
     } 
    }).start(); 
} 
Problemi correlati