Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

RxJava+RxAndroid (Lecture 20 – rx java)

822 views

Published on

RxJava+RxAndroid
https://university.noveogroup.ru

Published in: Education
  • Be the first to comment

RxJava+RxAndroid (Lecture 20 – rx java)

  1. 1. RxJava + RxAndroid Android Александр Вайцеховский
  2. 2. Реактивное программирование это парадигма программирования, ориентированная на потоки данных и распространение изменений © Wikipedia ООР[еактивное]П вместо методов и полей — реакции автоматическое пересчёт значений реакции зависят от изменений значений
  3. 3. ReactiveX Это комбинация лучших идей: паттерн Наблюдатель (Observer), паттерн Перечислитель (Iterator) и функциональное программирование. 1 void hello(String... names) { 2 Observable.from(names).subscribe(new Action1<String>() { 3 @Override 4 public void call(String s) { 5 Log.d("Hello " + s + "!"); 6 } 7 }); 8 } 9 10 hello("Ben", "George", "World"); Output: Hello Ben! Hello George! Hello World!
  4. 4. Что такое Observable Объект, предоставляющий асинхронный доступ ко множеству элементов: Связь с Iterator:
  5. 5. Примитивы RxJava 1 //Наблюдатель 2 interface Observer <T> { 3 void onCompleted(); 4 void onError(Throwable throwable); 5 void onNext(T t); 6 } 7 8 //Объект-наблюдения 9 class Observable <T> { 10 public final static <T> Observable<T> create(OnSubscribe<T> f); 11 public Subscription subscribe(Observer<? super T> observer); 12 } 13 14 //логика оповещения 15 interface OnSubscribe<T> extends Action1<Subscriber<? super T>> {} 16 17 //подписка 18 interface Subscription { 19 public void unsubscribe(); 20 public boolean isUnsubscribed(); 21 } 22 23 abstract class Subscriber<T> implements Observer<T>, Subscription {...}
  6. 6. Создание Observable 1 Observable<String> rxHelloWorld = 2 Observable.create(new Observable.OnSubscribe<String>() { 3 @Override 4 public void call(Subscriber<? super String> subscriber) { 5 subscriber.onNext("Hello"); 6 subscriber.onNext("World"); 7 subscriber.onCompleted(); 8 } 9 });
  7. 7. Создание Observable 1 void doWork(final Subscriber<? super String> subscriber) { 2 subscriber.onNext("Hello"); 3 subscriber.onNext("World"); 4 subscriber.onCompleted(); 5 } 6 7 Observable<String> rxHelloWorld = 8 Observable.create(new Observable.OnSubscribe<String>() { 9 @Override 10 public void call(Subscriber<? super String> subscriber) { 11 try { 12 doWork(); 13 } catch (Exception ex) { 14 subscriber.onError(ex); 15 } 16 } 17 });
  8. 8. Подписываемся на Observable 1 Subscription subsctiption = rxHelloWorld.subscribe(new Observer<String>() { 2 @Override 3 public void onCompleted() { 4 Log.d("completed"); 5 } 6 7 @Override 8 public void onError(Throwable throwable) { 9 Log.e(throwable); 10 } 11 12 @Override 13 public void onNext(String s) { 14 Log.d(s); 15 } 16 }); Hello World Completed
  9. 9. Потоки и Observable Предоставляет методы: observeOn(Thread) - поток, в котором выполнять логику налюдаемого объекта subscribeOn(Thread) - поток, в котором будут вызываться методы подписчика
  10. 10. Потоки и Observable
  11. 11. Трансформации 1 Observable<Integer> toLength(Observable<String> source){ 2 return source.map(new Func1<String, Integer>() { 3 @Override 4 public Integer call(String s) { 5 return s.length(); 6 } 7 }); 8 } 9 10 toLength(rxHelloWorld).subscribe(new Observer<Integer>() { 11 @Override 12 public void onCompleted() { Log.d("completed"); } 13 14 @Override 15 public void onError(Throwable throwable) { Log.e(throwable); } 16 17 @Override 18 public void onNext(Integer i) { Log.d(String.format("length: %d", i)); } 19 }); length: 5 length: 5 completed
  12. 12. Может быть красиво Java7 1 rxHelloWorld.map(new Func1<String, Integer>() { 2 @Override 3 public Integer call(String s) { 4 return s.length(); 5 } 6 }); Java8 1 rxHelloWorld.map((String s) -> { // 2 return s.length(); //можно так! 3 }); // 4 rxHelloWorld.map((String s) -> s.length()); //или так 5 rxHelloWorld.map((s) -> s.length()); //или упростить 6 rxHelloWorld.map(s -> s.length()); //или совсем просто 7 rxHelloWorld.map(String::length); //o_O * Но Android не поддерживает Java8:( ** Зато есть Retrolambda
  13. 13. Обычная логика
  14. 14. Реактивная логика
  15. 15. Упрощенное создание Create - создать обычный Observable Just - создает Observable из Объекта (его и возвращает) From - создает Observable из Array, Iterable, Future Empty, Never, Throw - на каждый метод подписчика Timer, Interval - созданный периодичный Observable Repeat - Observable, который возвращает одно и то же
  16. 16. Другие операторы Трансформация Map - преобразовывает возвращаемое значение FlatMap - преобразовывает значение в результат другого Observable Buffer - возвращает комбинации значений Window, Scan, GroupBy... Комбинирование CombineLatest - возвращает самые последние значения исходных Observable Merge - объединяет возвращаемые значения Zip - объединяет каждое и возвращает результат объединения Математические операции Max, Min - ждет конца, возвращает нужное Sum, Reduce - применяет функцию последовательно
  17. 17. Marble diagram RxJava wiki для объяснение каждого оператора использует Marble Diagram
  18. 18. Merge и Zip
  19. 19. Map и FlatMap
  20. 20. Filter и Debounce
  21. 21. Примеры
  22. 22. Async 1 Observable 2 .create((Subscriber<? super Bitmap> subscriber) -> { 3 try{ 4 Bitmap image = loadImage(); 5 subscriber.onNext(image); 6 subscriber.onCompleted(); 7 } catch (Exception ex) { 8 subscriber.onError(ex); 9 } 10 }) 11 .subscribeOn(Schedulers.io()) 12 .subscribe(() -> toast("loaded"));
  23. 23. View click 1 public static <T extends View> Observable<T> clicksFrom(T view) { 2 PublishSubject publishSubject = PublishSubject.create(); 3 view.setOnClickListener(new OnClickListener() { 4 @Override 5 public void onClick(View view) { 6 publishSubject.onNext(view)); 7 } 8 }); 9 return publishSubject.asObservable(); 10 } 11 clicksFrom(button).subscribe(view -> toast("clicked"));
  24. 24. Несколько событий 1 final ImageView imageView = (ImageView) findViewById(R.id.image); 2 3 Observable<Bitmap> imageObservable = 4 loadImage() 5 .cache() 6 .observeOn(AndroidSchedulers.mainThread()); 7 8 9 imageObservable.subscribe((Bitmap image) -> imageView.setImageBitmap(image)); 10 imageObservable 11 .flatMap(image -> { 12 clicksFrom(imageView).map((ImageView view) -> image) 13 }) 14 .subscribe((Bitmap image) -> processImage(image)); Что здесь происходит? Когда будет вызван setImageBitmap? Когда будет вызван processImage?
  25. 25. Гамбургер
  26. 26. Поддержка Retro t 1 class SimpleProfile { 2 private int id; 3 public String getId() {return id;} 4 } 5 6 class Network { 7 @GET("/users") 8 Observable<List<SimpleProfile>> getUsers(); 9 10 @GET("/users/{id}") 11 Observable<ProfileDetails> getUser(@Path("id") int id); 12 } 13 14 network.getUsers() 15 .flatMap((List<SimpleProfile> list) -> Observable.from(list)) 16 .flatMap((SimpleProfile profile) -> api.getUser(profile.getId())) 17 //.filter((ProfileDetails details) -> details.getSex() == Sex.FEMALE) 18 //.take(5) 19 //.doOnNext((ProfileDetails details) -> saveToDatabase(details)) 20 .subscribe((ProfileDetails details) -> handleProfile(details));
  27. 27. Обработка ошибок! 1 showProgressBar(); 2 network.getUsers() 3 .flatMap(Observable::from) 4 .subscribe(new Subscriber<String>() { 5 @Override 6 public void onNext(String user) { 7 listAdapter.add(user); 8 } 9 10 @Override 11 public void onCompleted() { 12 hideProgerssBar(); 13 showListView(); 14 } 15 16 @Override 17 public void onError(Throwable e) { 18 hideProgerssBar(); 19 hideListView(); 20 showErrorView(); 21 } 22 });
  28. 28. RxAndroid 1. Удобная работу с потоками 2. Работа с Android Lifecycle - RxLifecycle 3. Работа с View - RxBinding 4. SqlBrite - обертка над базой 5. и еще RxLocation / RxPermissions / RxNoti cation
  29. 29. RxAndroid - Threads Main Thread 1 Observable.just("one", "two", "three", "four", "five") 2 .subscribeOn(Schedulers.newThread()) 3 .observeOn(AndroidSchedulers.mainThread()); Handler Thread 1 final Handler handler = new Handler(); // bound to this thread 2 Observable.just("one", "two", "three", "four", "five") 3 .subscribeOn(Schedulers.newThread()) 4 .observeOn(AndroidSchedulers.handlerThread(handler));
  30. 30. RxLifecycle Bindings 1 IntentFilter intentFilter = new IntentFilter(WifiManager.WIFI_STATE_CHANGED_ACTION) 2 RxBroadcastReceiver.create(context, intentFilter)
  31. 31. RxBinding clicks - обработка нажатий 1 ViewObservable.clicks(mCardNameEditText, /*emit initial value*/ false) 2 .subscribe((View view) -> handleClick(view)); text - обработка ввода текста 1 ViewObservable.text(editTextName, false) 2 .subscribe((EditText editText) -> handleText(editText.getText()))); input - обработка "чекбоксов" 1 ViewObservable.input(compoundButton, false) 2 .subscribe((Boolean value) -> changeState(value));
  32. 32. Полезные ссылки ReactiveX RxJava RxAndroid Grokking RxJava, part 1 ищите там же части 2, 3, 4 ..или перевод на русский FRP on Android

×