2017-12-22 7 views
1
swipeRefreshLayout.setOnRefreshListener(() -> { 
swipeRefreshLayout.setRefreshing(true); 
retrieveData(mCardAdapter, db); 
}); 

次の方法は、メインのUIスレッドをブロックしていますが、バックグラウンドで実行する必要があります。たとえば、retrieveData()を実行すると、リフレッシュインジケータがハングします。実行する前に進捗ダイアログを初期化すると、それもハングアップし、私はRecyclerViewをスクロールできません。私は根本的に何かを誤解していますか?私は確かではないですが、onNext()方法でローカルデータストアへのリモートデータを追加すると、ブロックしものになるかもしれないと考えていRetrofit/ReactiveXメソッドは実際にデータを非同期で取得しますか?

public void retrieveData(final CardAdapter mCardAdapter, SQLiteHelper db) { 
CausticRetrofitService service = ServiceFactory.createRetrofitService(CausticRetrofitService.class, CausticRetrofitService.SERVICE_ENDPOINT); 
service.getMedia() 
    .subscribeOn(Schedulers.newThread()) 
    .observeOn(AndroidSchedulers.mainThread()) 
    .subscribe(new Subscriber <MediaResponse>() { 
    @Override 
    public final void onCompleted() { 

    Log.e("CausticRetrofitService", "Caustic Request Completed!"); 

    /* Cancel all progress indicators after data retrieval complete */ 
    setRefreshingFalse(); 

    // TODO: Add media to local data store and then display them one-by-one in real-time 
    mCardAdapter.addData(db.getAllMediaImages()); // Add all media images to card views 
    Log.d(getClass().toString(), "Added to local database: " + db.getAllMediaImages()); 
    mCardAdapter.notifyDataSetChanged(); 
    } 

    @Override 
    public final void onError(Throwable e) { 
    /* Cancel all progress indicators on data retrieval error */ 
    setRefreshingFalse(); 

    Toast.makeText(getApplicationContext(), "Cannot retrieve data. Please try again later.", Toast.LENGTH_SHORT).show(); 
    Log.e("CausticRetrofitService", e.getMessage()); 
    } 

    @Override 
    public final void onNext(MediaResponse mediaResponse) { 
    if (mediaResponse != null) { 

    Log.e("CausticRetrofitService", "Returned objects: " + mediaResponse.getResults()); 

    for (String mediaId: mediaResponse.getResults()) { 
     Log.e("CausticRetrofitService", mediaId); 
    } 

    List <String> mediaIds = mediaResponse.getResults(); 
    Log.d(getClass().toString(), "All Media IDs: " + mediaIds); 

    if (mediaIds.isEmpty()) { 
     Toast.makeText(getApplicationContext(), "Cannot retrieve data. Please try again later.", Toast.LENGTH_SHORT).show(); 
    } 

    mCardAdapter.clear(); 
    mCardAdapter.notifyDataSetChanged(); 

    /* Store objects from remote web service to local database */ 
    for (String mediaId: mediaIds) { 
     // TODO: Why are these null? 
     Log.d(getClass().toString(), "Media Id: " + mediaId); 
     MediaImage newMediaImage = new MediaImage(); 
     newMediaImage.setTitle(mediaId); 
     db.addMediaImage(newMediaImage); // Add media image to local database 
    } 

    } else { 
    Log.e("CausticRetrofitService", "Object returned is null."); 
    } 

    } 

    }); 
} 

答えて

1

あなたのネットワーク呼び出しは、指定したように、新しいスレッドで行われますが、加入者法onNext()とメインスレッドで観察Scheduler、上onComplete()実行されます。

これらのデータベース操作では、doOnNext()オペレータを使用して、バックグラウンドスレッドにキャッシュをオフロードしようとしているようです。

doOnNext()とは、ストリーム内の各エミッションに対して呼び出されるということです。

それはcacheData()は、すべてのDBの呼び出しを行う方法であること

service.getMedia() 
    .doOnNext(data -> cacheData(data)) 
    .subscribeOn(Schedulers.newThread()) 
    .observeOn(AndroidSchedulers.mainThread()) 

ような何かを行くことができます。 onNext()onComplete()に残っている唯一のものは、UIの更新だけです。

関連する問題