Upgrade to Pro — share decks privately, control downloads, hide ads and more …

RxJava for Android explained

Erik Hellman
December 04, 2015

RxJava for Android explained

Three simple and naive examples of using RxJava for Android. May be useful for beginners to get started.

Also contains examples of using RxBindings, Retrolambda and SqlBrite

Erik Hellman

December 04, 2015
Tweet

More Decks by Erik Hellman

Other Decks in Programming

Transcript

  1. Observable and Observer private static String[] DATA = new String[]

    {/* some data */}; 
 public Observable<String> getData() {
 return Observable.from(DATA);
 }
 
 public void printData() {
 Subscription dataSubscription = getData()
 .subscribe(new Action1<String>() {
 @Override
 public void call(String dataItem) {
 System.out.println(dataItem);
 }
 });
 }
  2. Retrolambda to the rescue! private static String[] DATA = new

    String[] {/* some data */}; 
 public Observable<String> getData() {
 return Observable.from(DATA);
 }
 
 public void printData() {
 Subscription dataSubscription = getData()
 .subscribe(System.out::println); }
  3. Operators private static String[] DATA = new String[] {/* some

    data */}; 
 public Observable<String> getData() {
 return Observable.from(DATA);
 }
 
 public void printData() {
 Subscription dataSubscription = getData()
 .map(String::toLowerCase) .subscribe(System.out::println); }
  4. Text change listener EditText searchQuery = (EditText) findViewById(R.id.search_query);
 searchQuery.addTextChangedListener(new TextWatcher()

    {
 @Override
 public void beforeTextChanged(CharSequence s, int start, int count, int after) { }
 
 @Override
 public void onTextChanged(CharSequence s, int start, int before, int count) { }
 
 @Override
 public void afterTextChanged(Editable editText) {
 if(editText.length() > 3) {
 mSearchHandler.obtainMessage(SEARCH_MSG, editText.toString()).sendToTarget();
 }
 }
 });
  5. Throttling API calls private class SearchHandlerCallback implements Handler.Callback {
 private

    long mLastTimesStamp;
 
 @Override
 public boolean handleMessage(Message msg) {
 long timeStamp = SystemClock.elapsedRealtime();
 if(timeStamp > (mLastTimesStamp + QUERY_TIME_LIMIT)) {
 List<String> searchResult = doSearch((String) msg.obj);
 runOnUiThread(new Runnable() {
 @Override
 public void run() {
 // Update RecyclerView with result...
 }
 });
 mLastTimesStamp = timeStamp;
 }
 return true;
 }
 }
  6. Filter, throttle, transform, retry on error and back to main

    thread… subscription = RxTextView.afterTextChangeEvents(searchQuery)
 .filter(changeEvent -> changeEvent.editable().length() > 3)
 .debounce(150, MILLISECONDS)
 .switchMap(changeEvent -> doSearch(changeEvent.toString()))
 .retryWhen(new RetryOnConnectivity()) .subscribeOn(Schedulers.io())
 .observeOn(AndroidSchedulers.mainThread())
 .subscribe(mSearchResultAdapter::setSearchResult);
  7. Kitten DAO public class Kitten {
 public long id;
 public

    String name;
 public String photoUri;
 public String description;
 }
  8. Cursor -> Kitten function public static Kitten cursorToKitten(Cursor cursor) {


    Kitten kitten = new Kitten(); 
 int idIdx = cursor.getColumnIndex(COLUMN_ID);
 kitten.id = cursor.getLong(idIdx); 
 int nameIdx = cursor.getColumnIndex(COLUMN_NAME);
 kitten.name = cursor.getString(nameIdx); 
 int photoUriIdx = cursor.getColumnIndex(COLUMN_PHOTO_URI);
 kitten.photoUri = cursor.getString(photoUriIdx); 
 int descIdx = cursor.getColumnIndex(COLUMN_DESCRIPTION);
 kitten.description = cursor.getString(descIdx); 
 return kitten;
 }
  9. SqlBrite queries @Override
 protected void onResume() {
 super.onResume();
 sqlBrite =

    SqlBrite.create();
 BriteContentResolver resolver = sqlBrite.wrapContentProvider(getContentResolver()); 
 subscription = resolver.createQuery(KITTEN_URI, Kitten.COLUMNS, null, null, null, true)
 .mapToList(MainActivity::cursorToKitten)
 .subscribe(mAdapter::setKittens);
 }
  10. Create a global Subject public class MyApp extends Application {


    private PublishSubject<Event> mSubject;
 
 @Override
 public void onCreate() {
 super.onCreate();
 mSubject = PublishSubject.create();
 }
 // This should be replaced with Dependency Injection public PublishSubject<Event> getSubject() {
 return mSubject;
 }
 }
  11. Create an Event class public class Event {
 public long

    timeStamp;
 public String name;
 public String description;
 public Type type;
 
 public enum Type {
 Kitten, Dog, Rabbit
 }
 }

  12. Use a simple Service @Override
 public int onStartCommand(Intent intent, int

    flags, int startId) {
 ((MyApp) getApplication()).getSubject().onNext(buildEvent());
 return START_NOT_STICKY;
 }
  13. Subscribe to event in your Activity List<Kitten> mKittens = new

    LinkedList<>(); mEventSubscription = ((MyApp) getApplication()).getSubject()
 .filter(event -> event.type.equals(Event.Type.Kitten))
 .map(event -> {
 Kitten kitten = new Kitten();
 kitten.name = event.name;
 kitten.description = event.description;
 return kitten;
 })
 .subscribe(mKittens::add);
  14. Missed an event? public class MyApp extends Application {
 


    private BehaviorSubject<Event> mSubject;
 
 @Override
 public void onCreate() {
 super.onCreate();
 mSubject = BehaviorSubject.create();
 }
 
 public BehaviorSubject<Event> getSubject() {
 return mSubject;
 }
 }