0

I need to get the content type from a specific URL. I know that we can do it by simply coding:

URL url = new URL("https://someurl.com");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("HEAD"); // Request Method: GET/POST/UPDATE...
connection.connect();
String contentType = connection.getContentType();

Since this blocks the UI thread (a synchronous operation), how to make a HTTP request using RxJava 2 on Android?

Notes:

  • I don't want to make this using the AsyncTask. Why?
  • This is related to RxJava 2 and not version 1.
  • Give me a clear, simple and concise example if you can.
Filipe Brito
  • 5,329
  • 5
  • 32
  • 42
  • 2
    Note that all of the problems with `AsyncTask` that Dan Lew cites in that blog post can be overcome, and that using RxJava 2 requires you to take similar steps. RxJava, even with RxAndroid, is not some "miracle cure". It's certainly a fine approach, and feel free to use it. Personally, I would not bother with `HttpURLConnection`, though. FWIW, [here is a sample app](https://github.com/commonsguy/cw-graphql/tree/v0.2/Trips/CW/DynamicOk) using RxJava/RxAndroid with OkHttp to make an HTTP request (specifically from a GraphQL endpoint). – CommonsWare Jul 28 '17 at 20:34

2 Answers2

0

Use RxJava just operator to leave main thread and continue the process on thread from computation scheduler and then use flatMap to make http call and find content type, network calls should run on threads from IO scheduler and finally observe on main thread and subscribe to result.

Observable.just(1).subscribeOn(Schedulers.computation())
       .flatMap(dummyValueOne -> {
          return Observable.just(getContentType).subscribeOn(Schedulers.io()); 
       }).observeOn(AndroidSchedulers.mainThread()).subscribe(new Consumer<String>() {
                    @Override
                    public void accept(String contentType) throws Exception {
            //do nextsteps with contentType, you can even update UI here as it runs on main thread
                    }
                }, new Consumer<Throwable>() {
                    @Override
                    public void accept(Throwable throwable) throws Exception {
                        Log.e("GetContentType", "exception getting contentType", throwable);
                    }
                }));
Arnav Rao
  • 6,692
  • 2
  • 34
  • 31
0

You can use a Callable. Here's an example,

Observable.fromCallable((Callable<Object>) () -> {
    // do stuff
    return object;
})
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(new Observer<Object>() {
            @Override
            public void onSubscribe(@NonNull Disposable d) {
                // so that this can be properly disposed in onDestroy()
                compositeDisposable.add(d);
            }

            @Override
            public void onNext(@NonNull Object object) {
                // do stuff with the result
            }

            @Override
            public void onError(@NonNull Throwable e) {
            }

            @Override
            public void onComplete() {
            }
        });
Sujit
  • 1,653
  • 2
  • 9
  • 25