Using Fast Android Networking Library With RxJava (original) (raw)

What is RxJava?

RxJava is used for reactive programming. In reactive programming, the consumer reacts to the data as it comes in. Reactive programming allows for event changes to propagate to registered observers.

The main components: observables, observers, and subscriptions

RxJava provides Observables and Observers. Observables can send out values. Observers watch Observables by subscribing to them.

Observers are notified when an Observable emits a value and when the Observable says an error has occurred. They are also notified when the Observable sends the information confirming that it no longer has any values to emit.

The corresponding functions are onNext, onError, and onCompleted() from the Observer interface. An instance of Subscription represents the connection between an observer and an observable. We can call unsubscribe() on this instance to remove the connection.

Let’s understand this better by exploring an example:

Observable observable = Observable.just("Cricket", "Football");

This is an Observable which emits strings and it can be observed by an Observer.

Let’s create an Observer:

Observer observer = new Observer() { @Override public void onCompleted() {

}

@Override
public void onError(Throwable e) {
    
}

@Override
public void onNext(String response) {
    Log.d(TAG, "response : " + response);
}

};

Now, we have to connect both Observable and Observer with a subscription. Only then can it actually do anything:

observable.subscribe(observer);

This will cause the following output, one line at a time:

This means the Observable emits two strings, one by one, which are observed by Observer.

RxJava is an Art and endless possibilities await those who can master it. So let’s start mastering it by learning how to use it with the network layer.

Found this project useful ❤️

Now using RxJava with Fast Android Networking

Add this in your build.gradle

compile 'com.amitshekhar.android:rx-android-networking:1.0.0'

For RxJava2

compile 'com.amitshekhar.android:rx2-android-networking:1.0.0'

RxJava2 Support, check here.

Then initialize it in onCreate() Method of application class :

AndroidNetworking.initialize(getApplicationContext());

I will try to give you a more friendly introduction to RxJava Operators, with plenty of complete code samples that you can actually compile and modify. If you read all the examples here, you will be able to learn most of the RxJava operators.

Using Map Operator

/*

Using Zip Operator - Combining two network request

/*

/*

}

/*

}

/*

}

private List filterUserWhoLovesBoth(List cricketFans, List footballFans) { List userWhoLovesBoth = new ArrayList<>(); // your logic to filter who loves both return userWhoLovesBoth; }

Using FlatMap And Filter Operators

/*

/*

}

/*

}

Using Take Operator

/* Here first of all, we get the list of users from server.

/*

}

getUserListObservable() .flatMap(new Func1<List, Observable>() { // flatMap - to return users one by one @Override public Observable call(List usersList) { return Observable.from(usersList); // returning user one by one from usersList. } }) .take(4) // it will only emit first 4 users out of all .subscribeOn(Schedulers.newThread()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Observer() { @Override public void onCompleted() { // do something onCompletion }

        @Override
        public void onError(Throwable e) {
            // handle error
        }

        @Override
        public void onNext(User user) {
            // only four user comes here one by one
        }
    });

Using flatMap Operator

/* Here first of all, we get the list of users from server.

/*

}

/*

}

/*

}

Using combination of flatMap with zip Operator

/* Very Similar to above example, only change is

/*

}

Binding Networking with Activity Lifecycle

public class SubscriptionActivity extends Activity {

private static final String TAG = SubscriptionActivity.class.getSimpleName();
private static final String URL = "http://i.imgur.com/AtbX9iX.png";
private String dirPath;
private String fileName = "imgurimage.png";
Subscription subscription;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    dirPath = Utils.getRootDirPath(getApplicationContext());
    subscription = getObservable()
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(getObserver());
}


@Override
protected void onDestroy() {
    super.onDestroy();
    if (subscription != null) {
        // unsubscribe it when activity onDestroy is called
        subscription.unsubscribe();
    }
}

public Observable<String> getObservable() {
    return RxAndroidNetworking.download(URL, dirPath, fileName)
            .build()
            .getDownloadObservable();
}

private Observer<String> getObserver() {
    return new Observer<String>() {
        @Override
        public void onCompleted() {
            Log.d(TAG, "onCompleted");
        }

        @Override
        public void onError(Throwable e) {
            Log.d(TAG, "onError " + e.getMessage());
        }

        @Override
        public void onNext(String response) {
            Log.d(TAG, "onResponse response : " + response);
        }
    };
}

}

Making a GET Request

RxAndroidNetworking.get("https://fierce-cove-29863.herokuapp.com/getAllUsers/{pageNumber}") .addPathParameter("pageNumber", "0") .addQueryParameter("limit", "3") .build() .getJSONArrayObservable() .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Observer() { @Override public void onCompleted() { // do anything onComplete } @Override public void onError(Throwable e) { // handle error } @Override public void onNext(JSONArray response) { //do anything with response } });

Making a POST Request

RxAndroidNetworking.post("https://fierce-cove-29863.herokuapp.com/createAnUser") .addBodyParameter("firstname", "Amit") .addBodyParameter("lastname", "Shekhar") .build() .getJSONObjectObservable() .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Observer() { @Override public void onCompleted() { // do anything onComplete } @Override public void onError(Throwable e) { // handle error } @Override public void onNext(JSONObject response) { //do anything with response } });

Downloading a file from server

RxAndroidNetworking.download("http://i.imgur.com/AtbX9iX.png",dirPath,imgurimage.png) .build() .setDownloadProgressListener(new DownloadProgressListener() { @Override public void onProgress(long bytesDownloaded, long totalBytes) { // do anything with progress
} }) .getDownloadObservable() .subscribeOn(Schedulers.io() .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Observer() { @Override public void onCompleted() { // do anything onComplete } @Override public void onError(Throwable e) { // handle error } @Override public void onNext(String response) { //gives response = "success" } });

Uploading a file to server

RxAndroidNetworking.upload("https://fierce-cove-29863.herokuapp.com/uploadImage") .addMultipartFile("image", new File(imageFilePath)) .build() .setUploadProgressListener(new UploadProgressListener() { @Override public void onProgress(long bytesUploaded, long totalBytes) { // do anything with progress
} }) .getJSONObjectObservable() .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Observer() { @Override public void onCompleted() { // do anything onComplete } @Override public void onError(Throwable e) { // handle error } @Override public void onNext(JSONObject response) { //do anything with response } });

Using it with your own JAVA Object - JSON Parser

/--------------Example One -> Getting the userList----------------/ RxAndroidNetworking.get("https://fierce-cove-29863.herokuapp.com/getAllUsers/{pageNumber}") .addPathParameter("pageNumber", "0") .addQueryParameter("limit", "3") .build() .getObjectListObservable(User.class) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Observer<List>() { @Override public void onCompleted() { // do anything onComplete } @Override public void onError(Throwable e) { // handle error } @Override public void onNext(List users) { // do anything with response
Log.d(TAG, "userList size : " + users.size()); for (User user : users) { Log.d(TAG, "id : " + user.id); Log.d(TAG, "firstname : " + user.firstname); Log.d(TAG, "lastname : " + user.lastname); } } });
/--------------Example Two -> Getting an user----------------/ RxAndroidNetworking.get("https://fierce-cove-29863.herokuapp.com/getAnUser/{userId}") .addPathParameter("userId", "1") .build() .getObjectObservable(User.class) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Observer() { @Override public void onCompleted() { // do anything onComplete } @Override public void onError(Throwable e) { // handle error } @Override public void onNext(User user) { // do anything with response Log.d(TAG, "id : " + user.id); Log.d(TAG, "firstname : " + user.firstname); Log.d(TAG, "lastname : " + user.lastname); } }); /-- Note : TypeToken and getParseObservable is important here --/

Error Code Handling

public void onError(Throwable e) { if (e instanceof ANError) { ANError anError = (ANError) e; if (anError.getErrorCode() != 0) { // received ANError from server // error.getErrorCode() - the ANError code from server // error.getErrorBody() - the ANError body from server // error.getErrorDetail() - just a ANError detail Log.d(TAG, "onError errorCode : " + anError.getErrorCode()); Log.d(TAG, "onError errorBody : " + anError.getErrorBody()); Log.d(TAG, "onError errorDetail : " + anError.getErrorDetail()); // get parsed error object (If ApiError is your class) ApiError apiError = error.getErrorAsObject(ApiError.class); } else { // error.getErrorDetail() : connectionError, parseError, requestCancelledError Log.d(TAG, "onError errorDetail : " + anError.getErrorDetail()); } } else { Log.d(TAG, "onError errorMessage : " + e.getMessage()); } }

In RxJava, you can do too many things by applying the operators (flatMap, filter, map, mapMany, zip, etc) available in RxJava.

License

   Copyright (C) 2016 Amit Shekhar
   Copyright (C) 2011 Android Open Source Project

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.

Contributing to Fast Android Networking

Just make pull request. You are in!