2017-10-06 13 views
1

Je suis confronté au problème.BlockingGet thread UI thread RxJava 2

J'essaie d'appeler RxJava à la manière de la synchronisation, mais cela entraîne le blocage du thread principal.

Voici mon code

@Override 
    public Single<SettingsBundle> getSettings() { 
     SettingsBundle settingsModel = mSettingsManager.getSettings(); 
     return Single.just(settingsModel).map(mSettingsMapper); 
    } 

Et voici mon appel de synchronisation

@Override 
    public SettingsBundle getSettingsSync() { 
     return getSettings().blockingGet(); 
    } 

Lorsque vous appelez le getSettingsSync le thread principal est bloqué, mais parfois, il fonctionne très bien, ce qui est plus problématique.

J'ai essayé quelque chose comme ça

@Override 
public SettingsBundle getSettingsSync() { 
    return getSettings() 
      .subscribeOn(Schedulers.newThread()) 
      .observeOn(AndroidSchedulers.mainThread()) 
      .blockingGet(); 
} 

Mais il Stills reste bloqué. Ce que je fais mal, je serais reconnaissant pour toute aide.

Merci.

+0

Un blocage bloquera jusqu'à ce qu'il y ait des données. N'utilisez pas un sur le fil de l'interface utilisateur. Utilisez un autre thread ou utilisez un appel non bloquant. –

+0

Quel est votre problème exactement? L'appel 'blockingGet()' bloquera le thread _current_ jusqu'à ce que les données soient disponibles, c'est le comportement attendu. Que veux-tu accomplir? –

+0

@ GergelyKőrössy, il n'est pas libéré ce qui bloque mon thread – bxfvgekd

Répondre

1
.observeOn(AndroidSchedulers.mainThread()) 
.blockingGet(); 

Le problème existe dans cette combinaison spécifique d'opérateurs. AndroidSchedulers planifie l'exécution du code sur le thread principal, mais le blockingGet() empêche l'exécution de code sur ce thread. Il suffit de mettre AndroidSchedulers et les opérateurs de blocage de RxJava ne fonctionnent pas bien ensemble. Comme le planificateur android peut être utilisé dans la construction de l'observable, cela signifie que toute utilisation des opérateurs blocking* sur le thread principal sera sujette à des interblocages indépendamment de ce que vous essayez de faire.

0

TL, TR

ne jamais utiliser observeOn(AndroidSchedulers.mainThread()) avec blockingGet()


Version longue

La sortie pour:

class MainActivity : AppCompatActivity() { 

    override fun onCreate(savedInstanceState: Bundle?) { 
     super.onCreate(savedInstanceState) 
     setContentView(R.layout.activity_main) 

     val result = 
       Single.just("Hello") 
       .subscribeOn(Schedulers.io()) 
       // .observeOn(AndroidSchedulers.mainThread()) 
       .map { 
        println("1. blockingGet `$it` thread: ${Thread.currentThread()}") 
        [email protected] it 
       } 
       .blockingGet() 
     println("2. blockingGet `$result` thread: ${Thread.currentThread()}") 
    } 
} 

est

1. blockingGet `Hello` thread: Thread[RxCachedThreadScheduler-1,5,main] 
2. blockingGet `Hello` thread: Thread[main,5,main] 

Comme vous pouvez voir le résultat a été généré sur thread principal (ligne 2), la fonction de carte a été exécuter dans le fil RxCachedThreadScheduler.

Avec la ligne .observeOn(AndroidSchedulers.mainThread()) décompressé le blockingGet() ne reviendra jamais et tout est bloqué.