2017-01-13 1 views
1

Ich bin neu in rxjava oder rxandroid und ich möchte meine AsyncTask und Rückruf-Hölle zu observable und subscriber ändern. Aber ich habe ein Problem damit. Ich muss zwei Anfragen an meine Datenbank stellen.NetworkOnMainThreadException in der flatMap

Meine Antwort von der ersten Anfrage wird ein Ergebnis für die zweite Anfrage sein. Ich versuche das mit flatMap zu lösen. Erste Anfrage Rückgabewert und alles ist in Ordnung, aber nächste Anfrage geben Sie mir NetworkOnMainThreadException.

Ich weiß, dass die Anfrage auf der main thread ausführen, aber warum? Ich versuche subscribeOn(Schedulers.io()) vor flatMap hinzuzufügen, aber das Ergebnis ist das gleiche. Könntest du mir dabei helfen und erklären, was ich falsch mache? Danke im Voraus. Mein Code ......

private void getFavouriteList(){ 
    Observable.create((Observable.OnSubscribe<PaginatedScanList<UserDO>>) subscriber -> { 
     final Map<String, AttributeValue> filterExpressionAttributeValues = new HashMap<>(); 
     filterExpressionAttributeValues 
       .put(":val1", new AttributeValue().withS(sharedPreferences.getString("socialId", ""))); 
     final DynamoDBScanExpression scanExpression = new DynamoDBScanExpression() 
       .withFilterExpression("socialId = :val1") 
       .withExpressionAttributeValues(filterExpressionAttributeValues); 
     PaginatedScanList<UserDO> result = dynamoDBMapper.scan(UserDO.class, scanExpression); 
     Log.d(TAG, "first result size " + result.size()); 
     subscriber.onNext(result); 
     subscriber.onCompleted(); 
    }) 
      .subscribeOn(Schedulers.io()) 
      .observeOn(AndroidSchedulers.mainThread()) 
      .filter(result -> { 
       if(result.isEmpty()) { 
        Toast.makeText(context, "Can not find user", Toast.LENGTH_SHORT).show(); 
        return false; 
       } 
       return true; 
      }) 
      .flatMap(user -> Observable.from(user.get(0).getFavourites())) 
      .subscribeOn(Schedulers.io()) 
      .flatMap(result -> { 
       final Map<String, AttributeValue> filterExpressionAttributeValues = new HashMap<>(); 
       filterExpressionAttributeValues 
         .put(":val1", new AttributeValue().withS(result)); 
       filterExpressionAttributeValues 
         .put(":val2", new AttributeValue().withN("1")); 
       final DynamoDBScanExpression scanExpression = new DynamoDBScanExpression() 
         .withFilterExpression("productId = :val1 and selling = :val2") 
         .withExpressionAttributeValues(filterExpressionAttributeValues); 
       PaginatedScanList<ProductDO> res = dynamoDBMapper.scan(ProductDO.class, scanExpression); 
       Log.d(TAG, "second result size " + res.size()); 
       return Observable.from(res); 
      }) 
      .subscribe(new Subscriber<ProductDO>() { 
       @Override 
       public void onCompleted() { 
        favouriteProgressBar.setVisibility(View.INVISIBLE); 
       } 

       @Override 
       public void onError(Throwable e) { 
        e.printStackTrace(); 
        favouriteProgressBar.setVisibility(View.INVISIBLE); 
       } 

       @Override 
       public void onNext(ProductDO productDO) { 
        Log.d(TAG, "productId " + productDO.getProductId()); 
        product.add(productDO); 
        adapter.notifyDataSetChanged(); 
       } 
      }); 
} 
+0

http://stackoverflow.com/questions/6343166/how-to-fix-android-os-networkonmainthreadexception –

Antwort

1

Verschieben Sie Ihre .observeOn(AndroidSchedulers.mainThread()) zu kurz vor Ihrem Abonnement.

PS: Sie sollten nicht Observable.create() verwenden, es sei denn, es gibt keine andere Alternative.

Bearbeitet, um den Toast im Filterproblem zu beheben.

private void getFavouriteList(){ 
    Observable.create((Observable.OnSubscribe<PaginatedScanList<UserDO>>) subscriber -> { 
     final Map<String, AttributeValue> filterExpressionAttributeValues = new HashMap<>(); 
     filterExpressionAttributeValues 
       .put(":val1", new AttributeValue().withS(sharedPreferences.getString("socialId", ""))); 
     final DynamoDBScanExpression scanExpression = new DynamoDBScanExpression() 
       .withFilterExpression("socialId = :val1") 
       .withExpressionAttributeValues(filterExpressionAttributeValues); 
     PaginatedScanList<UserDO> result = dynamoDBMapper.scan(UserDO.class, scanExpression); 
     Log.d(TAG, "first result size " + result.size()); 
     subscriber.onNext(result); 
     subscriber.onCompleted(); 
    }) 
      .subscribeOn(Schedulers.io()) 
      .observeOn(AndroidSchedulers.mainThread()) 
      .filter(result -> { 
       if(result.isEmpty()) { 
        Toast.makeText(context, "Can not find user", Toast.LENGTH_SHORT).show(); 
        return false; 
       } 
       return true; 
      }) 
      .observeOn(Schedulers.io()) 
      .flatMap(user -> Observable.from(user.get(0).getFavourites())) 
      .flatMap(result -> { 
       final Map<String, AttributeValue> filterExpressionAttributeValues = new HashMap<>(); 
       filterExpressionAttributeValues 
         .put(":val1", new AttributeValue().withS(result)); 
       filterExpressionAttributeValues 
         .put(":val2", new AttributeValue().withN("1")); 
       final DynamoDBScanExpression scanExpression = new DynamoDBScanExpression() 
         .withFilterExpression("productId = :val1 and selling = :val2") 
         .withExpressionAttributeValues(filterExpressionAttributeValues); 
       PaginatedScanList<ProductDO> res = dynamoDBMapper.scan(ProductDO.class, scanExpression); 
       Log.d(TAG, "second result size " + res.size()); 
       return Observable.from(res); 
      }) 
      .observeOn(AndroidSchedulers.mainThread()) 
      .subscribe(new Subscriber<ProductDO>() { 
       @Override 
       public void onCompleted() { 
        favouriteProgressBar.setVisibility(View.INVISIBLE); 
       } 

       @Override 
       public void onError(Throwable e) { 
        e.printStackTrace(); 
        favouriteProgressBar.setVisibility(View.INVISIBLE); 
       } 

       @Override 
       public void onNext(ProductDO productDO) { 
        Log.d(TAG, "productId " + productDO.getProductId()); 
        product.add(productDO); 
        adapter.notifyDataSetChanged(); 
       } 
      }); 
} 
+0

Thaks, es ist wirklich helfen. Was ist das Problem mit "Observable.create()"? –

+0

Mit 'Observable.create()' ist es wirklich leicht, einen Fehler zu machen. Siehe [hier] (http://stackoverflow.com/documentation/rx-java/1418/observable/4633/create-an- observable#t=201701131129135582063) für die Dokumentation von Alternativen. – JohnWowUs

+0

Vielen Dank. Ich werde Ihre Antwort als richtig markieren –