RxJava - Programação assíncrona para Android.

Post on 20-Jan-2017

160 views 6 download

Transcript of RxJava - Programação assíncrona para Android.

RxJavaUm pouco sobre programação assíncrona e streams

1

O objetivo dessa apresentação é mostrar um pouco do poder do

RxJava o porque dele ser incrível

2

Quem sou eu• Clêrton Leal

• Nascido e criado em Fortaleza

• Vivendo em Belo Horizonte a pouco mais de 2 meses

• Atualmente trabalhando como consultor para Avenue Code

3

Um pouco de históriaSerá rápido eu prometo =)

4

Reactive Extensions é uma biblioteca, de programação orientada a eventos, desenvolvida pela Microsoft e liberada para o .NET framework em 2011.

Implementa e extende o padrão Observable clássico, porem com um tratamento mais refinado para threads.

5

Em 2012 a Netflix adota o uso de Reactive Extensions para seus módulos escritos em .NET e fica surpresa com a facilidade de programação assíncrona.

Em 2013 a Netflix libera um projeto open source chamado RxJava, uma implementação da especificação RX para Java. Possibilitando assim o uso de RX em todos os seus módulos escritos em Java e Scala.

6

Linguagems

7

• Java: RxJava

• JavaScript: RxJS

• C#: Rx.NET

• C#(Unity): UniRx

• Scala: RxScala

• Clojure: RxClojure

• C++: RxCpp

8

• Ruby: Rx.rb

• Python: RxPY

• Groovy: RxGroovy

• JRuby: RxJRuby

• Kotlin: RxKotlin

• Swift: RxSwift

• PHP: RxPHP

9

Uma sintaxe única para todas as linguagens

10

RxJavaObservable.create(new Observable.OnSubscribe<Integer>() { @Override public void call(Subscriber<? super Integer> observer) { try { for (int i = 1; i < 5; i++) { observer.onNext(i); } observer.onCompleted(); } catch (Exception e) { observer.onError(e); } } } );

11

RxGroovydef myObservable = Observable.create({ aSubscriber -> try { for (int i = 1; i < 5; i++) { aSubscriber.onNext(i); }

aSubscriber.onCompleted(); } catch(Throwable t) { aSubscriber.onError(t); }})

12

RxSwiftlet source = Observable.create { observer in do { for i in 1...5 { observer.on(.Next(i)) }

observer.on(.Completed) } catch { observer.on(.Error) }}

13

Qual a grande jogada do RxJava

14

15

RX trás a união e expansão de dois

padrões de projeto

16

Observable

17

Iterator

18

Observable extendido

19

Adicionando a isso funções de

transformação e tratamento

assíncrono de dados20

Entre o Observable e o Subscriber

podemos aplicar diversas funções de

transformação21

Um pequeno disclaimer sobre Java

8

22

Aplicando um filtroString[] search = {"google", "microsoft"};

Observable.from(search) .filter(s -> s.contains("g")) .subscribe(s -> { Log.d(TAG, s);});

23

24

Vamos adicionar o controle de threads

25

String[] search = {"google", "microsoft"};

Observable.from(search) .filter(s -> complexAndSlowFilter(s)) .subscribeOn(Schedulers.computation()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(s -> { Log.d(TAG, s);});

26

Schedulers• Schedulers.computation() - Usado para ações em CPU

bound em multi thread.

• Schedulers.io() - Usado para ações em IO bound.

• Schedulers.newThread() - Execução em nova thread.

• Schedulers.immediate() - Execução na thread atual.

• Schedulers.trampoline() - Execução na thread atual, mas apenas após outras ações enfileiradas.

27

SchedulersAndroidSchedulers.mainThread() Main thread de uma aplicação Android.

28

Vamos para um exemplo pratico

29

Em quantas linhas?

• Campo de texto irá buscar em um serviço web

• Buscas feitas apenas com pelo menos 3 caracteres

• Buscas feitas apenas quando o usuário passar 500 milissegundos sem digitar

30

Precisamos criar um observable do SearchViewpublic Observable<String> getSearchObservable(SearchView searchView) { return Observable.create(new Observable.OnSubscribe<String>() { @Override public void call(Subscriber<? super String> subscriber) { searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() { @Override public boolean onQueryTextSubmit(String query) { return false; }

@Override public boolean onQueryTextChange(String newText) { subscriber.onNext(newText); return true; } }); } }); }

31

E depois aplicar algumas transformaçõespublic Observable<String> getSearchObservable(SearchView searchView) { return Observable.create(new Observable.OnSubscribe<String>() { @Override public void call(Subscriber<? super String> subscriber) { searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() { @Override public boolean onQueryTextSubmit(String query) { return false; }

@Override public boolean onQueryTextChange(String newText) { subscriber.onNext(newText); return true; } }); } }).filter(s -> fragment != null) .map(s -> "http://search.com.br/" + s) .filter(s -> s.length() >= 3) .debounce(500, TimeUnit.MILLISECONDS) .observeOn(AndroidSchedulers.mainThread()) .observeOn(Schedulers.computation());

32

E apenas isso na sua camada de visãogetSearchObservable(searchField).subscribe(s -> { doRequest(); })

33

Vamos ver alguns truques legais com

RxJava

34

Facil de cancelar• Sempre que chamamos o método subscribe(), o retorno do

mesmo é uma Subscription.

• Uma subscription pode ser facilmente cancelada.Subscription subscription = getSearchObservable(searchField).subscribe(s -> { doRequest();});

subscription.unsubscribe();

35

Morte a AsyncTask

36

AsyncTasks são tóxicas para o seu

código.

37

AsyncTask<String, String, User> asyncTask = new AsyncTask<String, String, User>() { @Override protected void onPreExecute() { // Show a progress dialog }

@Override protected User doInBackground(String... params) { return getUserSync(params[0]); }

@Override protected void onPostExecute(User s) { // Update the UI }

@Override protected void onProgressUpdate(String... values) { // Notify progress }};

38

Método getUserpublic Observable<User> getUser(String name) { return Observable.create((Observable.OnSubscribe<User>) subscriber -> { try { User user = getUserSync(name); subscriber.onNext(user); subscriber.onCompleted(); } catch (IOException e) { subscriber.onError(e); } }).subscribeOn(Schedulers.io());}

39

Consumindo getUserprivate void doRequest() { getUser("José") .observeOn(AndroidSchedulers.mainThread()) .subscribe(user -> { updateUi(user); }, throwable -> { handleError(throwable); });}

40

Ou apenas use o Retrofit@GET("/{name}")Observable<User> getUser(@Path("name") String name);

41

Morte a TimerTask

42

Um timer simples com RxJavaSubscription subscription = Observable.timer(START_DELAY, POLL_INTERVAL, TimeUnit.SECONDS) .subscribe(aLong -> { Log.d(TAG, String.valueOf(aLong)); });

subscription.unsubscribe();

43

A simplicidade de fazer tarefas de forma assíncrona abre novas

possibilidades44

Qualquer operação de IO deve ser realizada em uma thread

separada. Isso inclui acesso a banco de dados e

SharedPreferences

45

O maior motivo se adotar RxJava é o

suporte da comunidade

46

Existem muitas bibliotecas com Suporte a RxJava• Retrofit: https://github.com/square/retrofit

• RxBinding: https://github.com/JakeWharton/RxBinding

• SqlBrite: https://github.com/square/sqlbrite

• Rx-preferences: https://github.com/f2prateek/rx-preferences

47

Obrigado =)Contatos

• clertonleal@gmail.com

• clertonleal

48