Rxjava and Volley Requests
Asked Answered
P

2

23

My question should sounds something like stupid, but i am just jumping from Asynktask to RxJava. So:

Is possible to use RxJava Observable with Volley Requests?, it means, using future requests.

I ask this, because another httpClient like retrofit uses RxJava very well, but personally love Volley, so is it possible?

Edit

Base on the first answer, i get that it is possible.

Could you share some sample showing how to do that?

Presumptuous answered 21/9, 2015 at 17:35 Comment(6)
yes. Use RequestFuture and Observable.fromGelderland
ok, if it is possible, will edit my question to get some sample. In volley to return value, i normally use callbacks, but here, i have no idea how to do that.Presumptuous
I just happen to be trying to figure out how to do this, too. I am reading this right now: code.hootsuite.com/…Canary
thanks, i just read this, and its very helpfull. Will try some codePresumptuous
@MaxPinto RequestFuture in Volley is a listener that wraps into a future, which you can use with Rx.Gelderland
yes, i found the answer, will show my code to hel some otherPresumptuous
P
13

THIS CODE WOKS WITH THIS LIBRARY

api 'com.netflix.rxjava:rxjava-android:0.16.1'

Finally and thanks for your answer i find a solution that want to share:

In my case i use Activities, but for fragment should be more or less equal.

And i want o get a JsonObject in response, but could be your custom Volley implementation.

 public class MyActivity extends BaseActivityWithoutReloadCustomer implements Observer<JSONObject>

{
private CompositeSubscription mCompositeSubscription = new CompositeSubscription();
private Activity act;

 /**
 * @use handle response from future request, in my case JsonObject.
 */
 private JSONObject getRouteData() throws ExecutionException, InterruptedException {
    RequestFuture<JSONObject> future = RequestFuture.newFuture();
    String Url=Tools.Get_Domain(act.getApplicationContext(), Global_vars.domain)+ PilotoWs.wsgetRoutesbyUser+ Uri.encode(routeId);
    final Request.Priority priority= Request.Priority.IMMEDIATE;
    Estratek_JSONObjectRequest req= new Estratek_JSONObjectRequest(Request.Method.GET, Url,future,future,act,priority);
    POStreet_controller.getInstance().addToRequestQueue(req);
    return future.get();
}

 /**
 *@use the observable, same type data Jsob Object
 */
 public Observable<JSONObject> newGetRouteData() {
    return Observable.defer(new Func0<Observable<JSONObject>>() {
        @Override
        public Observable<JSONObject> call() {
            Exception exception;
            try {
                return Observable.just(getRouteData());
            } catch (InterruptedException | ExecutionException e) {
                Log.e("routes", e.getMessage());
                return Observable.error(e);
            }
        }
    });
};

@Override
public void onCreate(Bundle instance) {
    super.onCreate(instance);
    setContentView(R.layout.yourLayout);
    act = this;

    /**
     * @condition: RxJava future request with volley
     */

     mCompositeSubscription.add(newGetRouteData()
            .subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
            .subscribe(this));
 }


@Override
public void onCompleted() {
    System.out.println("Completed!");
}

@Override
public void onError(Throwable e) {
    VolleyError cause = (VolleyError) e.getCause();
    String s = new String(cause.networkResponse.data, Charset.forName("UTF-8"));
    Log.e("adf", s);
    Log.e("adf", cause.toString());
}

@Override
public void onNext(JSONObject json) {
    Log.d("ruta", json.toString());
}

For me, it just works. Hope helps some one.

Edit Estratek_JSONObjectRequest.java

public class Estratek_JSONObjectRequest extends JsonObjectRequest{
Activity Act;
Priority priority;

public Estratek_JSONObjectRequest(int method, String url,
                                  JSONObject jsonRequest, Listener<JSONObject> listener,
                                  ErrorListener errorListener,Activity act, Priority p) {
    super(method, url, jsonRequest, listener, errorListener);
    this.Act=act;
    this.priority=p;
}

public Estratek_JSONObjectRequest(int method, String url,
                                  Listener<JSONObject> listener,
                                  ErrorListener errorListener,Activity act, Priority p) {
    super(method, url, null, listener, errorListener);
    this.Act=act;
    this.priority=p;
}

@Override
public Map<String, String> getHeaders()  {
    HashMap<String, String> headers = new HashMap<String, String>();
    headers.put("Content-Type", "application/json; charset=utf-8");
    headers.put("Authorization", "Bearer "+Tools.mySomeBearerToken);
    return headers;
}

//it make posible send parameters into the body.
@Override
public Priority getPriority(){
    return priority;
}

protected Response<JSONObject> parseNetworkResponse(NetworkResponse response) {
    try {
        String je = new String(response.data, HttpHeaderParser.parseCharset(response.headers));
        if (je.equals("null")){
            je="{useInventAverage:0}";
            return Response.success(new JSONObject(je), HttpHeaderParser.parseCacheHeaders(response));
        }
        else
            return Response.success(new JSONObject(je), HttpHeaderParser.parseCacheHeaders(response));
    } catch (UnsupportedEncodingException var3) {
        return Response.error(new ParseError(var3));
    } catch (JSONException var4) {
        return Response.error(new ParseError(var4));
    }
}

}

This is like Volley constructors, but i make my own custom, to send some headers, like bearer token, content-type, send priority, etc. Otherwise is the same.

FOR THE RXJAVA2 LIBRARY, THIS IS THE WAY:

> build.gradle should have something like this:

api "io.reactivex.rxjava2:rxandroid:2.0.2":

public class MainActivity extends AppCompatActivity {
CompositeDisposable         mCompositeDisposable = new CompositeDisposable();

@Override
public void onCreate(Bundle instancia) {
    super.onCreate(instancia);
    setContentView(R.layout.sale_orders_list);

    // disposable that will be used to subscribe
    DisposableSubscriber<JSONObject> d = new DisposableSubscriber<JSONObject>() {
        @Override
        public void onNext(JSONObject jsonObject) {
            onResponseVolley(jsonObject);
        }
        @Override
        public void onError(Throwable t) {
            // todo
        }

        @Override
        public void onComplete() {
            System.out.println("Success!");
        }
    };

    newGetRouteData()
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(d);
}

@Override
public void onDestroy(){
    super.onDestroy();
    /**
     * @use: unSubscribe to Get Routes
     */
    if (mCompositeDisposable != null){
        mCompositeDisposable.clear();
    }
}


/**
 * @condition: RxJava future request with volley
 */
private JSONObject getRouteData() throws ExecutionException, InterruptedException,RuntimeException {
    RequestFuture<JSONObject> future = RequestFuture.newFuture();
    String Url = "https//miapirest.com/api";
    JSONObjectRequest req= new JSONObjectRequest(Request.Method.GET, Url,future,future,act,priority);


    VolleyInstance.addToRequestQueue(req);

    return future.get();
}

/**
 * @condition: this function create a new Observable object and return that if success or
 */
public Flowable<JSONObject> newGetRouteData() {
    return Flowable.defer(new Callable<Publisher<? extends JSONObject>>() {
        @Override
        public Publisher<? extends JSONObject> call() throws Exception {
            return Flowable.just(getRouteData());
        }
    });
};

}

Presumptuous answered 21/9, 2015 at 19:0 Comment(6)
Could you post Estratek_JSONObjectRequest ? or some generic form of it?Canary
i just have added few moments agoPresumptuous
What does "je" mean in parseNetworkResponse? Is that just something specific to your data?Canary
yes, it is specific return, in your case you can just as normalPresumptuous
your code has a litter error~ if meet a exception like authfail exception create by volley, my program will throw an error, I fix catch like this ` try { return Observable.just(future.get()); } catch (InterruptedException e) { return Observable.error(e); } catch (ExecutionException e) { return Observable.error(e.getCause()); } `Upstream
You are right, i found ruta too, but o havent edited this. Thanks for thatPresumptuous
E
5

Good news is that Mr.张涛 kymjs modified Google Volley into RxVolley, Removed the HttpClient and RxJava support.

RxVolley = Volley + RxJava + OkHttp

Complete documentation available at http://rxvolley.mydoc.io/

P.S: I'm currently thinking of how to use RxVolley with support for multiple custom JSON converters like retrofit!

Elayneelazaro answered 21/1, 2016 at 7:45 Comment(3)
another a little more extended version including converters also is jus: github.com/apptik/jusBeadledom
@djodjo Thanks for sharing !Elayneelazaro
why httpClient removed?Haft

© 2022 - 2024 — McMap. All rights reserved.